launching a UIViewcontroller from a UITableViewController crashes app - iphone

I have a UItableViewController. Inside this class there is the following method where I am trying to launch another UIViewController. I tried to connect the two using a segue and gave it a identifier, then used this version:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"About to launch MyDetail View controller");
[self performSegueWithIdentifier:#"myDetailSegue" sender:self];
}
That didnt work, the app froze and I got a message in the main.m file as follows: " "Thread 1 received signal Sigabrt"
So then deleted the segue and tried to instantiate the UIViewcontroller as follows,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"About to launch my Detail View controller");
UIStoryboard *sboard = [UIStoryboard storyboardWithName:#"iPhone" bundle:nil];
UIViewController *myDetailVC = [sboard instantiateViewControllerWithIdentifier:#"myDetailVC"];
[self.navigationController pushViewController:myDetailVC animated:YES];
}
which worked. But now Im confused. Why would the UIStoryboard way work and the segue not???
Could someone please help, Im so confused.

I don't get understand what exactly problem you are facing but i want tell you that because of you are using uitableview first please connect its cell to new view controller and select 'Push' segue method. Once you have done this then add following code in your application instead to user didselectrowatindexpath methods.
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
/*
When a row is selected, the segue creates the detail view controller as the destination.
Set the detail view controller's detail item to the item associated with the selected row.
*/
if ([[segue identifier] isEqualToString:#"Showcategorydetails"]) {
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
CategoryDetailsController *detailViewController = [segue destinationViewController];
detailViewController.category_title = [maincategories_array objectAtIndex:selectedRowIndex.row];
}
}

Related

navigation from tableview to another view

I am working in a table view app using story board . I want to perform event on selection
of cell in table view . So when I select a cell element , a next view(detailview) should be
open for displaying further details .
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.dv = [[Detail alloc]initWithNibName:#"Detail" bundle:nil];
dv.dic = [self.arr1 objectAtIndex:indexPath.row];
[self.view addSubview:dv.view];
}
Instead try this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.dv = [[Detail alloc]initWithNibName:#"Detail" bundle:nil];
dv.dic = [self.arr1 objectAtIndex:indexPath.row];
[self presentViewController:dv animated:YES completion:nil];
}
And if you want to dismiss use this code:
[self dismissViewControllerAnimated:YES completion:nil];
You should use a navigation controller and when selecting a row, push the detail view into it.
To create navigation controller: selected the tableview controller and go Editor / Embed in / Navigation Controller.
Then do:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// dv = [Detail alloc] initWithNibName:#"Detail" bundle:nil];
dv = [storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
dv.dic = [self.arr1 objectAtIndex:indexPath.row];
[self.navigationController pushViewController:dv];
}
The commented line is if you're not using storyboard.
Or you can do as Abdullah suggested, but implement a dismiss button with
[self dismissViewControllerAnimated:YES completion:nil];
In the storyboard drag a segue from the viewcontroller icon at the bottom of your view to the next viewcontroller you want to segue to. Make sure that your view is embedded in a navigation controller. Press the arrow that appears between your tableviewcontroller and the target view controller and make sure you label it with a segue identifier. Then in the method you are describing make sure they selected the correct index path with an if statement and write
[self performSegueWithIdentifier:#"theNameOfYourIdentifierFromTheStoryboard"];
That being said, I think that there is a large body of information you should research.
Read this: http://www.appcoda.com/use-storyboards-to-build-navigation-controller-and-table-view/ as a start.

navigating from detail view controller to table view controller

i am facing a situation that i am loading data correctly to a uitableviewcontroller. also i am loading data correctly to the detail view controller.
what i am using:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowPaymentDetails"])
{
DetailPaymentViewController *detailViewController = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.paymentsTableView indexPathForSelectedRow];
detailViewController.payment = [arrayOfPayment objectAtIndex:[myIndexPath row]];
}
}
the problem i have is that when i am going back (through normal drag and drop swipe) the uitableviewcontroller is reloaded. since this takes data from a web service ... i don't want to reload the data.
Can you help me on any ideas on this.
Thnx in advance.
I'm guessing your segueing to the TableViewController from the DetailViewController. I think your creating a new TableViewController and not going back to the original one. You can check this in the debugger by setting a breakpoint in viewWillApear and looking at the value of self.
(lldb) po self
$0 = 0x1ddd2480
You should do this in your DetailViewController to go back to the TableViewController.
[self.navigationController popViewControllerAnimated:YES];

UITableView didSelectRowAtIndexPath with prepareForSegue but didLoadView is not called

I am learning iOS and I have written a simple iPhone app using iOS 5. The app shows a UITableView populated with Speakers' names, when I select one of the names its supposed to go to a UIViewController and show details about that person (name, address, etc), so its really two ViewControllers a UITableViewController and UIViewController (both subclassed).
So, in MICSpeakersTableViewController : UITableViewController I have this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MICSpeakerDetailViewController *detailViewController = [[MICSpeakerDetailViewController alloc] initWithNibName:#"Detail" bundle:nil];
[detailViewController setSpeaker:[[self getSpeakers] objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:detailViewController animated:YES];
}
which gets called when I select it and populates the speaker (in that its not nil and description matches).
Then I have this in the same implementation:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [ self.tableView indexPathForCell:sender];
if ([segue.identifier isEqualToString:#"Detail"])
[segue.destinationViewController setSpeaker:[[self getSpeakers] objectAtIndex:indexPath.row]];
}
Which also gets called and the segue.identifier is Detail and the destinationViewController's speaker is set correctly (is not nil, description matches). I am not quite sure why I have to set that again since I am setting it in didSelectRowAtIndexPath but I set it again and it seems harmless.
Finally, in the MICSpeakerDetailViewController, the initWithNibName method is called and the self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; returns an instance.
However, the segue never happens and viewDidLoad is never called.
Its probably something small but I can't figure it out... any advice?
Edit: Here is a screenshot of the storyboard showing the segue and the controllers:
You have to embed the view controllers in a navigation controller for push segues to work. I don't know why it lets you define them without this in place.
To do this, click on your table view controller, then choose Editor --> Embed In --> Navigation Controller. If you should also be within a tab bar controller, then the navigation controller is embedded in that in a similar fashion. You should see the following:
Your segue will now work.

segue from UITableViewController doesn't work as push, only as modal

I have this view stack:
UIViewController --> (Modal segue) -->
UITabBarController --> (relationship) -->
UINavigationController --> (relationship) -->
UITableViewController --> (segue) --> UIViewController
Here is my segue code in the UITableViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"selected row...");
[self performSegueWithIdentifier:#"showVmail" sender:self];
NSLog(#"done segue");
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showVmail"]) {
NSLog(#"Got segue request...");
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
[segue.destinationViewController setMyVmail: [self.vmails objectAtIndex:indexPath.row]];
}
}
When I click on an item in the table view controller, I see these log messages:
selected row...
Got segue request...
Setting myVmail... // from the new view controller
done segue
And it doesn't move onto my new view controller.
If I change to a Modal, segue it works, but of course there is no Back button.
As far as I can see, Ive done everything correctly. Ive read many a response on stack overflow, with the same issue, and their resolution is to put in the UINavigationController. Ive already done this.
Any thoughts would be muchly appreciated!
I tried the suggestion seen else where that you should go back to simple cases. I changed the UINavigationController in the storyboard to point to a basic UIViewController and then for that to have a button that segued to another UIViewController. When I ran it, I still got my UITableViewController!
That is when I remembered that I was programatically filling in the objects in the UITabBarController, and that I wasn't invoking the UINavigationController, but skipping that and invoking the UITableViewController! So in fact, I really was having the same issue as everyone else, missing the UINavigationController !
Change my program in to link the UINavigationController instead of the UITableViewController and all is now working as expected.

Code is exectuting but the view is not loading when called form a function?

I am doing a book kinda application using a viewBased application. The mainView acts as the backgroundView for loading pages. Each page is a different view and have its own nib. When i swipe on a page(actually on the mainView which have loaded the current view/page), that page will be removed and the next/previous page will be added.
[currentPage.view removeFromSuperview];
[self.view insertSubview:nextPage.view atIndex:0];
I have added a popoverController with a barbutton in this mainView. Its intialized with a tableviewController class named popClass. PopClass is another UITableViewController class which will act as the parent for the popViewController.
self.myPopController = [[PopController alloc] initWithStyle:UITableViewStylePlain];
self.myPopOverController = [[UIPopoverController alloc] initWithContentViewController:myPopController];
When I select certain row in the popover, I want the backgroundview(mainView) to load the page corresponding to the number of the row.
For that I have written a function in bookView(mainView) Controller class. And is calling it from the popOver's parent class when i select certain row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger toPageNumber = indexPath.row + 1;
[viewController changeToPage:toPageNumber];
}
Function and the lines of code are executing but nothing is happening. Even the log lines are printed but no action takes place. The code is the same for removing a page and adding another page which is working successfully when i swipe the view/page.
What is the problem? OR is there anyother way to make the view change in mainView by using the popover?
You need to have refernce of the background view controller in the popover controller.
In the PopController controller you should have a delagate like:
#interface PopController: UITablViewController{
//// other varibales;
id delegate;
}
#property (nonatomic, retain) id delgate;
Now from the class in which you are showing the popovercontroller
you should add this line:
[myPopController setDelegate:self];
Then you can easily acces any method of the main view controller class. By using
[delegate callTheRequiredMethod];
Hope this helps.
Thanks,
Madhup
It's hard to tell what's going wrong without looking at the code. That said, here's what I'd do:
(1) When a row is selected in mainView, present the popoverController modally:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PopoverViewController *vc = [[PopoverViewController alloc] init];
[self.navigationController presentModalViewController:vc animated:YES];
[vc release];
}
(2) When something changes in the popoverController, for example a row is selected, set a value in the parentViewController (which should be the MainView):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.parentViewController.value = someValue;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
(3) Dismiss the popoverController where-ever you choose by calling:
[self dismissModalViewControllerAnimated:YES]`