UITableView didSelectRowAtIndexPath with prepareForSegue but didLoadView is not called - iphone

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.

Related

Blank detail view pushed from a TableView that was created programmatically

My setup is using a storyboard in which I create a login, then a home screen in which the user can press a button to display their messages.
These are displayed in a table which is instantiated programmatically.
From this table I then want to press a row to go into detail about that row, but when i do this the view displayed is blank but all methods associated with the class are being fired (view did load, and so on).
I have literally tried 10 different ways from different solutions others had had suggested on their questions but nothing works.
Code to make new view and push it:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
messageDetail *messageDetailView = [[messageDetail alloc]initWithNibName:nil bundle:nil];
messageDetailView.message = [entityObjects objectAtIndex:indexPath.row];
[self.navigationController pushViewController:messageDetailView animated:YES];
}
ViewDidLoad of DetailView:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"Message Detail:\n%#",message);
messageTitle.text = message.message_title;
messageBody.text = message.message_xml;
}
I have tried using a segueIdentifier route and then intercepting the prepareSegue: to add data to the new view, but as the tableView is created programmatically there is no segue.
I have tried instantiating the view from storyboard via:
messageDetailView = [self.storyboard instantiateViewControllerWithIdentifier:#"MDV"];
But the app crashes as there is no view with identifier, even though i set the identifiers.
You send nil as nib name, if you do not have a nib file do not allocate the message detail view with initWithNibName function.
Use raw init or initWithFrame. Whichever works for you.
Good luck
I basically did the same thing with this code here. Hope this helps
Detail_View *next=[[Detail_View alloc] initWithNibName:#"Detail_View" bundle:nil];
//These are just values that I needed to set before going to the next page.
//You can use this if you want to pass over the value of your table row
//otherwise ignore this
next.htmlContents= [[storage_array objectAtIndex:indexPath.row]objectForKey:#"title"];
next.titleText=[[storage_array objectAtIndex:indexPath.row] objectForKey:#"title"];
[self.navigationController pushViewController:next animated:YES];

UITableView in a UIViewController linked to another ViewController (DetailController)

I have an app on the store that uses a RootViewController linking to a UIViewController (DetailController) and I am working on a new app which basically requires the need for this same feature. But instead, my new app has a UITableView inside a UIViewController linked to a UIViewController. So I thought, i'd copy and paste my RootViewController code into this new UIViewController. So i've linked up the TableView, set delegate and datasource to self and the TableView shows the titles of the items (Hurrah) but when touched, doesn't go to the DetailController? I've used NSLog to determine what part isn't working and of course its the didSelectRowAtIndexPath method… and here is my code
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *theItem = [items objectAtIndex:indexPath.row];
DetailController *nextController = [[DetailController alloc] initWithItem:theItem];
[self.navigationController pushViewController:nextController animated:YES];
[nextController release];
}
The TableViewCell just highlights blue and doesn't link to DetailController.
Thanks in advance!
By "not working" do mean it's not being called, or that it's not pushing the view controller? If the first, then make sure the table view delegate is set correctly. If the second, make sure both nextController and self.navigationController are not nil.

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.

UITableViewController Methods are not being called

As the title says none of my tableview controller methods are being called.
The steps I went through to create my table view are as follows.
1) I created a new file based on UITableViewController and selected the create with xib option. I Named my file myStuffViewController.
2) I have a rootview controller which is a UIViewController. In this view I have a navigation controller that I want to push my tableview controller onto at a certain point.
3) I setup my tableview and nav controller like so
mystuff = [[MyStuffViewController alloc]initWithNibName:#"MyStuffViewController"bundle:[NSBundle mainBundle]];
accountView = [[AccountView alloc] initWithNibName:#"Login" bundle:[NSBundle mainBundle]];
accountViewNavController = [[UINavigationController alloc] init];
accountViewNavController.delegate = self;
NSArray *ar= [NSArray arrayWithObjects:accountView,mystuff, nil];
[accountViewNavController setViewControllers:ar animated:NO];
[accountViewNavController popToRootViewControllerAnimated:NO];
accountView.title=#"Login";
4) Then when a user pushes a button I want to push the table view controller onto the stack like this.
[accountViewNavController pushViewController:mystuff animated:YES];
I've even tried calling [self.tableView reloadData] but none of the methods get called.
Could somebody propose why my table view methods are not being called?
EDIT 1
Just so I'm being as clear as I can be here is what my header file looks like. To be it doesnt seems like I'm missing anything.
#interface MyStuffViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate> {
RemixView *remixView;
NSMutableArray *remixListArray;
TBXML*tbxml;
}
#property(nonatomic,retain)NSMutableArray *remixListArray;
#property(nonatomic,retain)RemixView *remixView;
#property(nonatomic ,retain)TBXML *tbxml;
-(void)fetchRemixList:(NSString *)uid key:(NSString *)k1;
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
#end
Check
You declare in the .h file that you implement the two table view delegates UITableViewDelegate & UITableViewDatasource
In the NIB make sure you link to your delegate in file owner OR if you have created the TableView programmatically make sure you set the delegate ivar also.
Then see if the delegate methods start getting called

UITableView with multiple viewcontollers

I just filled my UITableView with Planets. I would like each cell clicked to open into a new Xib (if this sounds like the wrong approach please direct). I can get a secondviewcontroller working, its getting the thirdviewcontroller and fourthviewcontroller working? Thanks.
Place your main view controller (the one with the table) inside a UINavigationController. Then, when the user selects a row, push a new view controller onto it.
The following function will help. As Ben Gottlieb said your main view controller will need to be in a UINavigationController. You need to implement the delegate method for didSelectRowAtIndexPath and this is where you create the new controller for your new view and load it.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
YourViewController *controller = [[YourViewController alloc] initWithNibName:#"YourViewController"bundle:nil];
[[self navigationController] pushViewController:yourViewController animated:YES];
[yourViewController release]; // don't leak memory
}
Based on the row number you can decide which nib to load.