iOS Pass on label of row in UITableView - ios

I'm trying to pass on the label of a table row when you hit that rows accessory button as it matches the key of an array in a plist, so the next page knows which array to load the settings from.
This is the code I'm using at the moment in performSegueWithIdentifier:
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
SettingsViewController *destViewController = segue.destinationViewController;
destViewController.nameViewer = [viewerKeys objectAtIndex:indexPath.row];
Unfortunately every time it picks the first row... I know because using NSLog it always gives the same output (the name of the first row). Any Ideas?
Cheers,
Chris

The problem is that when you tap an accessory button of a cell, the cell itself doesn't get selected (this is normal behavior since accessory buttons fire a different delegate method), so you get always 0.
What you could do though is to set an ivar with the selected index inside tableView:accessoryButtonTappedForRowWithIndexPath: delegate method and pass that ivar to your destination controller. I hope that this makes sense...

Use -prepareForSegue:sender: instead of -prepareForSegue: and use the following:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSIndexPath *indexPath = [[[segue sourceViewController] tableView] indexPathForCell:sender];
SettingsViewController *destViewController = segue.destinationViewController;
destViewController.nameViewer = [viewerKeys objectAtIndex:indexPath.row];
}

Related

Segues not working (Table view/navigation controller/tab controller)

I am writing an iOS app that uses the service Parse. When I tap on a cell, it doesn't segue as I would expect. It appears that my "prepareForSegue" method is not being called. I used breakpoints to determine this, and the NSLog never outputs anything. Here is my method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
NSLog(segue.identifier);
if ([segue.identifier isEqualToString:#"showObjectDetails"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
//OfferDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
[segue.destinationViewController setObject:object];
}
}
The segue name is "showObjectDetails" if it matters, and it's coming from a list view. I used the Push selection segue. I have made sure that the Custom Class is set correctly in Interface Builder. I am using a Tab Bar controller, that references a NavigationController, that then displays the tableview.
Make sure that the Segue Identifier has been set in the Storyboard, as below.

Pushing Data from UITableViewCell to ViewController

I am trying to push data from a UITableViewCell into another view controller. I have tried two separate ways, instantiateViewControllerWithIdentifier and also PrepareForSegue. In both instances the ViewController loads correctly but the data is not being passed across (either null, or the first array value).
Here is my instantiateViewControllerWithIdentifier method, when I log the variable within my ViewController it just returns null.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *testNumber = [jobNumberArray objectAtIndex:indexPath.row];
NSLog(#"Job is... %#",testNumber);
StandardInfoViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"StandardInfoViewController"];
controller.JobNr = [jobNumberArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
Prepare For Segue
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"Details" sender: self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Details"]){
StandardInfoViewController *controller = (StandardInfoViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
controller.jobNumber = [jobNumberArray objectAtIndex:indexPath.row];
}
}
When I use the prepareForSegue call I get the first row of my Array, which I understand because it doesn't know the cell, but I don't know how to identify the Cell within the prepareForSegue call.
I hope this makes sense, and any help or pointers would be greatly appreciated.
Thanks
If you drag the segue FROM the tableView-cell in the storyboard, you will then get the cell itself as parameter sender.
then you can use tableView indexPathForCell:sender to get the actual index of the selected cell. Then just fetch your object normally.
I.e. you will not need to implement didSelectRowAtIndexPath
If you still want to use didSelectRowAtIndexPath, just pass the cell as the sender parameter manually. I.e:
[self performSegueWithIdentifier:#"Details"
sender:[self.tableView cellForRowAtIndexPath:indexPath]]
Although your first version with instansiateViewController should work, judging by your code.
Another pattern is to subclass the cells themselves, and let them have a property that is the object that they want to display. Then you can just fetch the object directly from the cell without calling the data-array itself.
Is this what you want?
This is how you identify Cell in prepareForSegue method.
**UITableViewCell *cell=[myTable cellForRowAtIndexPath:path];**
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Details"]){
StandardInfoViewController *controller = (StandardInfoViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
**UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];**
controller.jobNumber = [jobNumberArray objectAtIndex:indexPath.row];
}
}

Can i use same detailedViewController with different segue variables

this is my problem. I can perfectly show a detailedViewController came from a table view, but i got 2 more tableview that i want to make it seem in detailed.When i gave it same variables - since every things that came same - it still doesn't go to the next view controller.I checked segue identifier aswell and i really don't want to make a new detailed controller.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
// Get destination view
detailViewController *destViewController = [segue destinationViewController];
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSInteger tagIndex = [(UIButton *)sender tag];
destViewController.recipeName =[[self.content objectAtIndex:indexPath.row] valueForKey:#"recipeName"];
destViewController.recipeDetail =[[self.content objectAtIndex:indexPath.row] valueForKey:#"recipeDetail"];
this is how i pass the data.They are exactly same with a small difference. The content of the content array.
You can go to the same view controller from multiple other controllers. You may be able to do this by simply creating the segue from the appropriate cells in each table. The way I've done it is to create a segue from each table view controller to the "detail" view controller, and then perform the segue in code when the appropriate cell is selected. Keep in mind that when creating segues in IB, there is a difference between creating them from table view cells and from the view controllers themselves.

Proper way of adding a Segue on a TableView Cell

I have an application where the user selects a certain row in a TableView, and the contents of that Row will be sent to the next ViewController.
So far, I have connected the TableView Cell/Row to the next ViewController via a Segue. The issue I am facing right now is passing the value of the selected row to the next ViewController. I have written code for the didSelectRowAtIndexPath and the prepareForSegue functions.
Here are the functions (In ViewController.m file, the one with the TableView):
The didSelectRowAtIndexPath function:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"didSelectRowAtIndexPath entered");
//itemNameList is a mutable array where I get my TableView data from
NSMutableString *itemName = [itemNameList objectAtIndex:indexPath.row];
//selectedItem is a global mutable string I use to store the selected item to.
selectedItem = itemName;
UIAlertView *messageAlert = [[UIAlertView alloc]
initWithTitle:#"Row Selected"
message:itemName
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
// Display Alert Message
[messageAlert show];
}
The prepareForSegue function:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"prepareForSegue entered");
if ([[segue identifier] isEqualToString:#"Details"])
{
//DetailViewController is the next ViewController once the user
//selects an item
DetailViewController *detailViewController = [segue destinationViewController];
//the first selectedItem is a property of the second ViewController
//the next selectedItem is the global mutable string
detailViewController.selectedItem = selectedItem;
}
}
The problem is that the prepareForSegue function executes first before the didSelectRowAtIndexPath function. This is a huge issue because that means I don't actually get to pass the value to the second ViewController since the second ViewController has loaded into the screen already.
Does anyone know how to deal with this?
My idea was to somehow get the Row the user selected in the prepareForSegue method but I don't know how to do that either.
Yes, you are right. The prepareForSegue seems to execute before didSelectRowAtIndexPath. So you would need to get selected row in prepareForSegue.
Use the method:
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]
Inside prepareForSegue to get selected row.
Remove the connection you made in the IB between the UItableViewCell and the ViewControllerB and add a segue between ViewControllera to ViewControllerB.
Add:
[self performSegueWithIdentifier:#"nextVC" sender:nil];
at the end of didSelectRowAtIndexPath.
That way prepareForSegue will be triggered after didSelectRowAtIndexPath finished processing.
In prepare for segue
if ([segue.identifier isEqualToString:#"YourIdentifier"]) {
TheNextViewController *tnvc = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
//then do whatever you have to do
//eg. set property in thenextviewcontroller by tnvc.propertyname = self..

Pass tableviewcell data with segue?

I have a popover segue that goes to a view controller. I want to set some properties in the view controller when a cell is clicked. I tried using -prepareForSegue:, but then I realized that it doesn't have the scope of the selected cell. I know that I have to use:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
delegate method, but I'm not sure how that will affect the popover segue. Do I have to programatically create the popover, or is there another way?
Thanks much!
~Carpetfizz
Use self.tableView.indexPathForSelectedRow to get the data from your table's data source, e.g., the array backing the table data. If, for some reason, you don't want to get the data from your data source, then the sender is the UITableViewCell that was tapped to trigger the segue.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YourSegueID"]) {
YourDestinationViewControllerClass* destinationController = segue.destinationViewController;
destinationController.somePublicProperty = self.yourTablesDataSourceArray[self.tableView.indexPathForSelectedRow.row];
UITableViewCell *cell = (UITableViewCell *)sender;
destinationController.someOtherPublicProperty = cell.textLabel.text;
}
}
So add an NSIndexPath propriety to your VC. Let's call it selectedCell. In your tableView:didSelectRowAtIndexPath method, save the selected index path to the instance variable.
Then in your prepareForSegue method, use the instance variable.
Alternately, in your prepareForSegue method, you could ask the table view for the currently selected row using the table view's indexPathForSelectedRow method.
The best approach is to use the indexPathForSelectedRow property.
For example you can write a code like this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YourSegueIdentifier"])
{
NSIndexPath *indexPath = [sender indexPathForSelectedRow];
NextViewController *vc = (NextViewController *)segue.destinationViewController;
vc.yourProperty = #"Some Value";
}
}
Assuming NextViewController as your segue destination controller and yourProperty as the property you want to set during the segue, you can access and set information from your parent controller because indexPathForSelectedRow automatically knows which cell has been clicked.
More information can be found here.

Resources