0

I'm working on an app where I want to display a tableView populated with users, and when the row is selected a new view is displayed containing a conversation (so basically a messaging app). For now I just want that when I touch a row on my FirstViewController, the SecondViewController is displayed with the name of the user selected on a label. But I can't get it to work because each time I touch a row, the indexPath is 0, si it is always the first user name that is displayed. Here is a part of my code:

#import "GSBChatViewController.h"
#import "GSBConversationViewController.h"



@interface GSBChatViewController ()
@property (weak, nonatomic) IBOutlet UITableView *userTableView;

@end

@implementation GSBChatViewController
@synthesize chatUsers;

- (void)viewDidLoad {
[super viewDidLoad];

GSBChatUsers *user1 = [[GSBChatUsers alloc]initWithName:@" John DOE" andPicture:@"photo.jpg" andLastMessage:@"Ca marche!"];
GSBChatUsers *user2 = [[GSBChatUsers alloc]initWithName:@"Justine DUBOIS" andPicture:@"photo.jpg" andLastMessage:@"Salut, ça va?"];
GSBChatUsers *user3 = [[GSBChatUsers alloc]initWithName:@"Jacques LAPORTE" andPicture:@"photo.jpg" andLastMessage:@"Réunion le 23 à 15h, c'est bon pour toi?"];
GSBChatUsers *user4 = [[GSBChatUsers alloc]initWithName:@"Guillaume DUPOND" andPicture:@"photo.jpg" andLastMessage:@"OK, parfait"];
GSBChatUsers *user5 = [[GSBChatUsers alloc]initWithName:@"Françoise MARTIN" andPicture:@"photo.jpg" andLastMessage:@"Tu as posé tes congés?"];
GSBChatUsers *user6 = [[GSBChatUsers alloc]initWithName:@"Jean-Jacques CELESTIN" andPicture:@"photo.jpg" andLastMessage:@"Je prends note"];

chatUsers = [[NSArray alloc]initWithObjects:user1,user2,user3,user4,user5,user6, nil];

}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}



#pragma mark - Navigation


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

NSIndexPath *indexPath = [self.userTableView indexPathForCell:sender];
NSLog(@"Path: %@",indexPath);

GSBConversationViewController *destVC = [segue destinationViewController];
GSBChatUsers *selectedUser =[chatUsers objectAtIndex:indexPath.row];

NSLog(@"%ld",[self.userTableView indexPathForCell:sender].row);
NSString *userName = selectedUser.name;

NSLog(userName);
destVC.Test=userName;

}


#pragma mark - Datasource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

// Retourne le nombre d'éléments de notre liste
NSLog(@"Number of rows: %ld",chatUsers.count);
return [chatUsers count];

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

// Instancie notre cellule par son identifier
GSBTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"userCell"];

// On récupère l'item que l'on va traiter
GSBChatUsers *user = [chatUsers objectAtIndex:indexPath.row];

// On affecte les valeurs de notre user aux éléments de notre cellule
[cell.userName setText:user.name];
[cell.profilePicture setImage:[UIImage imageNamed:user.picture]];
[cell.lastMessage setText:user.lastMessage];
NSLog(@"%@",chatUsers);

return cell;

}




- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"%@",_cellTitle);
//[self performSegueWithIdentifier:@"conversationSegue" sender:[chatUsers objectAtIndex:indexPath.row]];

}


@end

I looked at this answer as well as this one but none of them helped. (Well they helped because beforehand I couldn't even get the label's text to change).

Disclaimer: This is for a school project, and I'm one hundred percent allowed to ask for help on the Internet. As english is not my native language maybe I'm not clear on some points, please let me know if you need further informations.

Thanks for your help!

Community
  • 1
  • 1
nommis
  • 116
  • 10
  • so you have wired up the segue from the `FirstViewController` to the `SecondViewController` via drag&drop in storyboard? – André Slotta Mar 22 '16 at 22:15
  • @AndréSlotta Yes, from the prototype cell of the firstViewController to the secondViewController – nommis Mar 22 '16 at 22:24
  • well in that case you do not need the `didSelectRowMethod` but just `prepareForSegue`. and in `prepareForSegue` it always prints out row **0** right now? – André Slotta Mar 22 '16 at 22:26
  • @AndréSlotta Okay I'll remove that. Right now the first name on the tableView is John Doe, and this is the name that is displayed on the label of the secondVC for every row (although all rows have a different name on them). `NSLog(@"%ld",[self.userTableView indexPathForCell:sender].row);` Always gives me "0" in the console. – nommis Mar 22 '16 at 22:32
  • that's really strange. your code looks ok. can you share your project with me so i can take a look? – André Slotta Mar 22 '16 at 22:34
  • Sure, it's on [GitHub](https://github.com/nommis/gsb-app)! As this is my first app the project and the code are probably messy, I hope not too much! Thanks! – nommis Mar 22 '16 at 22:43

2 Answers2

0

it looks like the tableView in the storyboard is not connected to the outlet userTableView. therefore the row NSIndexPath *indexPath = [self.userTableView indexPathForCell:sender]; does not return the correct result.

go to your storyboard, connect the outlet to the tableview and try again!

outlet is not connected

André Slotta
  • 13,774
  • 2
  • 22
  • 34
  • Thanks for taking the time to help me! I tried that and it's still not working. I have to go to sleep now so I'll check all outlets connections tomorrow because if I forgot one there are chances that I forgot others. BTW if you want to test it you don't need a password just touch the logo on the login page! I'll let you know if I find something, thanks again for your time! – nommis Mar 22 '16 at 23:01
  • it works! you have to **connect the tableview's outlet** as i wrote in my solution and you also have to **delete the segue** once and **reinstall it** by dragging from the cell to the destinationviewcontroller. voila! :) – André Slotta Mar 22 '16 at 23:12
  • That's great! Thanks a lot for your help! I would never have thought of checking outlets, guess I'll think about it now! :) – nommis Mar 22 '16 at 23:15
0

If you dragged a segue on the storyboard from your table cell prototype to the view controller you want to push to, then you are halfway there. However, the segue will be triggered before the UITableViewDelegate is informed that the user "didSelectRowAtIndexPath", so navigation to the next view controller will happen before your code in that delegate method runs.

The solution is to override prepareForSegue:sender: in your FirstViewController. In this case, the sender will be the table cell that was tapped.

Your implementation could look something like this:

- (void)prepareForSegue:(UIStoryboardSegue *)segue
             sender:(id)sender {
    GSBTableViewCell *cell = (GSBTableViewCell *)sender;
    SecondViewController *destination = ((SecondViewController *)segue.destinationViewController);
    destination.view;  // Sadly, this is required to force the outlets to be connected in the destination view controller before you try to access them
    destination.userNameLabel.text = cell.userName.text;
}
Daniel Hall
  • 13,457
  • 4
  • 41
  • 37