So I have a UITableView, and the cells are connected to a UIStoryboardSegue in order to open a new UIViewController. After clicking a cell prepareForSegue get's called and everything works fine.
QUESTION: In the follwoing method how can i know what is the indexPath of the selected cell in my TableView?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
ObjectDetailViewController *mvc = [segue destinationViewController];
// PassingObject *obj = [self.array objectAtIndex: ? ];
mvc.passingObject = obj;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Assume self.view is the table view
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
DetailObject *detail = [self detailForIndexPath:path];
[segue.destinationViewController setDetail:detail];
}
Instead of [self.tableView indexPathForSelectedRow] (look at the DJPlayer answer) you can use [self.tableView indexPathForCell:sender], since sender is a selected cell in this case.
Related
I have a UICollectionView that segues to a Detail VC. The segue goes from custom cell to the detail.
I read here stackoverflow link that you can't use prepareForSeguethat you must use performSeguein didSelectItem
The issue is, I need to pass data. I tried using prepareForSegue anyways, but the cells are now not selectable. Ideas?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detailSegue"]) {
LPDiaryDetailViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [self.collectionView indexPathForCell:sender];
LocationImage *image = self.savedItems[indexPath.row];
NSLog(#"collectionView imageview %#", destViewController.thumbnailView);
destViewController.usernameLabel.text = [image valueForKeyPath:#"user.username"];
destViewController.locationLabel.text = [image valueForKeyPath:#"location.name"];
destViewController.captionString = image.caption;
}
}
Then I tried this with performSegue in didSelectItem and I created a method createLocationImageto call the detail VC to make a LocationImage in it's implementation, but the createLocationImage never gets called
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
LocationImage *testImage = (LocationImage*)self.savedItems[indexPath.row];
[self.diaryDetailVC createLocationImage:testImage];
[self performSegueWithIdentifier:#"detailSegue" sender:self];
}
Up until now I have used prepareForSegue method to notify a view controller he is about to review a segue from a different view controller, but if i'm the vc that sending the segue, will my prepareForSegue (in he same class of the segue sender) will check if there is a code to preform before he fires the segue?
I'm asking because I got a solution here to preform a simple segue just to go from stable view row which represent notes to the creation page of the note for editing...very simple, but from some reason it's not presenting my note in the creation page, only takes me to a new clean creation page..
So I though maybe it's because the prepareForSegue method..here you can see the question to give you more details How to to create a segue to push back to editing mode from a table view?
Would really appreciate to get your help on this.
This are the 2 methods I added to my NotesList table view controller:
#pragma mark - delegate
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"noteSegue" sender:nil];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"noteSegue"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NMNote *note = [self.notes objectAtIndex:indexPath.row];
NMCreateNotesViewController *destination = [segue destinationViewController];
destination.textField.text = note.content;
}
}
And I made sure the segue identifier in the storyboard is named noteSegue. So why its note working...Im getting a new TextView instead of populating it with the note content :/
This is the error i'm getting:
Thanks!
The prepareForSegue: method is called on the current VC not the destination. UIViewController Class Reference. You can use the method to obtain a reference to the destination VC and set variables/call methods on it before the segue is performed.
Calling the segue like this:
[self performSegueWithIdentifier:#"NAMEOFSEGUE" sender:nil];
You can then prepare the destination VC like this:
#import "NMCreateNotesViewController.h"
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NAMEOFSEGUE"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
[destination createNote]; /* or something similar */
}
}
EDIT:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NMNote *note = [self.notes objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"noteSegue" sender:note];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NAMEOFSEGUE"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
NMnote *note = (NMNote*) sender;
destination.textField.text = note.content;
}
}
To check if there is a code to preform before the segue you can use solution below:
if ([segue.destinationViewController isKindOfClass:[UIViewController class]]) {
UIViewController *nextVC = segue.destinationViewController;
if(nextVC respondsToSelector:#selector(yourMethod)){
[nextVC yourMethod];
}
}
You can check if you are sure to perform the specific segue by implementing this method
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
If you have your note presenting code in viewDidLoad, try moving that to viewDidAppear (in your note editing VC). There used to be an issue when presenting from a TableView row where the segue would fire after VDL was executed.
i have a project which is basically a uitableview populated with a mutable array and has a search bar
now the uitableview has title and subtitle which are populated with different mutable arrays ..
when you tap on a cell (from the view or from the search view) it pushes the title to a new view controller.
i need the subtitle to be pushed also to the new view controller
i tried every thing i know but i had no success
i have attached the project so you can see how its coded and possibly tell me how to fix it
http://ezzati.net/KuwaitFood.zip
please help
Please replace the function below.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowDetail"]) {
NSString *object = nil;
NSIndexPath *indexPath = nil;
if (self.searchDisplayController.isActive) {
indexPath = [[self.searchDisplayController searchResultsTableView] indexPathForSelectedRow];
object = self.results[indexPath.row];
} else {
indexPath = [self.tableView indexPathForSelectedRow];
object = self.objects[indexPath.row];
}
[[segue destinationViewController] setDetailLabelContents:object];
[[segue destinationViewController] setNumberdetailLabelContents:[sender detailTextLabel].text];
}
}
You have to assign a identifier to the segue (the arrow from your table view controller to the new controller in your storyboard) and then use this function to grab the destination view controller and set it's property with the data you want to send:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"identifier"])
{
SecondViewController *vc = [segue destinationViewController];
// get the selected item index
NSInteger index = [self.tableView indexPathForCell:sender].row;
// set the data property for the second view (pass data)
vc.theProperty = [self.data objectAtIndex:index];
}
Now you can find theProperty on your SecondViewController filled with data from the table view controller.
EDIT: I've reviewed your code. for your case do this:
in -tableView: didSelectRowAtIndexPath: change self to indexPath like this:
[self performSegueWithIdentifier:#"ShowDetail" sender:indexPath];
and in prepareForSegue do this:
DetailViewController *vc = [segue destinationViewController];
// get the selected item index
NSInteger index = ((NSIndexPath *)sender).row;
// index of searched object in self.objects
NSInteger trueIndex = [self.objects indexOfObject:[self.results objectAtIndex:index]];
// set the data property for the second view (pass data)
vc.detailLabelContents = [self.objects objectAtIndex:trueIndex];
vc.numberdetailLabelContents = [self.numbers objectAtIndex:trueIndex];
the problem was because you were using index of self.results and applying it to self.objects which was 0, so you were always getting the first object "You Tube"
change the last line of
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
as below
[[segue destinationViewController] setDetailLabelContents:[sender detailTextLabel].text];
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"DetailPlacePage"]) {
NSIndexPath *indexPath = [self.Allplace indexPathForSelectedRow];
NomadPlaceDetailViewController *placedetailcontroller = segue.destinationViewController;
placedetailcontroller.myDictionary = [self.placeArray objectAtIndex:indexPath.row];
}
}
This is the code I use to prepare segue for UIviewcontroller.
Can't see the next view controller , screen gets blank and just navigation bar is shown .
Try casting your NomadPlaceDetailViewController:
NomadPlaceDetailViewController *placedetailcontroller = (NomadPlaceDetailViewController *)segue.destinationViewController;
I do have a UITableViewController which can be edited.
I do have 2 Segues in my Storyboard, coming from the tableView going to an EditViewController (via modal) and the second one via Push to the DetailViewController.
I want, when the tableview isEditing, that the segue to editviewcontroller is executed, and when is not editing, than to DetailViewController.
I tried different ways, with the prepareforsegue method. then several tries with the didselectrowatindexpath method, where I stand now.
Now, when the tableView is in editing and I touch one cell, the detailviewcontroller pushes and on top of this the editviewcontroller comes in as modal view controller.
Here is my code.
Can you please give me hints:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"didSelectRowAtIndexPath %i", indexPath.row);
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (tableView.isEditing == FALSE) {
NSLog(#"isediting");
[self performSegueWithIdentifier:#"showDetail" sender:cell];
} else {
[self performSegueWithIdentifier:#"showEditPerson" sender:cell];
}
}
and here is what i have tried with the prepare for segue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *theChild = [myAppDelegate.myPersonsArray objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:theChild];
}
if ([[segue identifier] isEqualToString:#"showEditPerson"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *theChild = [myAppDelegate.myPersonsArray objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:theChild];
}
}
From my comment above:
It seems you have the prototype cell hooked up to a segue in addition to the delegate method. Fix the segue connections and you should be all set.