prepareForSegue called before didSelectRowAtIndexPath only when third segue is added
The reason is you can't drag from a tableview cell to multiple views. As @rdelmar mentioned this is wrong. You should drag from the destination to the source view and then handle manually the way I did above.
Also can be found here: Conditional segue performed on tap on UITableViewCell
Swift didSelectRowAtIndexPath and prepareForSegue
You can fetch the selected indexPaths from tableView in your prepare for segue
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "editSegue")
{
if let indexPath = tableView.indexPathForSelectedRow{
let viewController : WorkoutView = segue.destinationViewController as! WorkoutView
viewController.workoutInfoData = marrStudentData.objectAtIndex(indexPath.row) as! WorkoutInfo
navigationItem.title = ""
}
}
}
prepareForSegue called twice
You forgot the break
in the second and third case of your switch
maybe it will help ;)
Change your switch with :
switch (indexPath.row)
{
case CategoryFilter:
{
[self performSegueWithIdentifier:@"FilteredCategoryView" sender:self];
break;
}
case PriceFilter:
{
[self performSegueWithIdentifier:@"FilterByPriceSegue" sender:self];
break;
}
case ConditionFilter:
{
[self performSegueWithIdentifier:@"SearchFilterConditionSegue" sender:self];
break;
}
}
If you don't put the break
instruction in each of your cases the switch will do all the other case until the end of the switch or another break
instruction.
Use didSelectRowAtIndexPath or prepareForSegue method for UITableView?
If you use prepareForSegue:sender:
then you won't have as much to change if you later decide to trigger the segue from some control outside the table view.
The prepareForSegue:sender:
message is sent to the current view controller, so I'd suggest something like this:
- (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];
}
In Swift:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let path = self.tableView.indexPathForSelectedRow()!
segue.destinationViewController.detail = self.detailForIndexPath(path)
}
prepareForSegue getting called twice, with Attempt to present UINavigationController while presentation is in progress
The problem is prepareForSegue is called before didSelectRowAtIndexPath. You should just eliminate the didSelectRowAtIndexPath method, and do everything in prepareForSegue. You can use the following line to get the indexPath you need:
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
How to access segue in 'didSelectRowAtIndexPath'?
You should be using the didSelectRowAtIndexPath
method to determine whether or not a cell was selected, and send the indexPath
as the sender of the segue:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("showQuestionnaire", sender: indexPath);
}
Then in your prepareForSegue
method, get the indexPath
from the sender
parameter and use that to pass the correct row/data:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "showQuestionnaire") {
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! QuestionnaireController
let row = (sender as! NSIndexPath).row; //we know that sender is an NSIndexPath here.
let patientQuestionnaire = patientQuestionnaires[row] as! PatientQuestionnaire
controller.selectedQuestionnaire = patientQuestionnaire
}
}
To explain...
- I used the index path as the sender so I can easily pass the index path. You could also check for the currently selected cell using other UITableView methods, but I've always done it this way with success
- You can't put
performSegueWithIdentifier
within the prepare for segue method, becauseperformSegueWithIdentifier
leads toprepareForSegue
; You are just looping around and around with no aim. (When you want to perform a segue, prepareForSegue is always executed) prepareForSegue
doesn't run by itself when a row is selected. This is where you needdidSelectRowAtIndexPath
. You need aperformSegueWithIdentifier
outside of the method as described previously, which should be indidSelectRowAtIndexPath
UITableView didSelectRowAtIndexPath with prepareForSegue but didLoadView is not called
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 Topics
iOS 11 Core Nfc - Any Sample Code
Saving Coredata To-Many Relationships in Swift
Ios: Perform Upload Task While App Is in Background
Uitextfield Should Accept Number Only Values
Why Does My Uitableview "Jump" When Inserting or Removing a Row
Negative Spacer for Uibarbuttonitem in Navigation Bar on iOS 11
Are Afnetworking Success/Failure Blocks Invoked on the Main Thread
Slservicetypefacebook Setinitialtext Is Not Working
Modulename-Swift.H File Not Found in Xcode8
Border Around Uitableview Section
What Exactly Are Protocols and Delegates and How Are They Used in iOS
How to Wake Up iOS App with Bluetooth Signal (Ble)
Xcode 9 - Localization Issue Warning Storyboard
Programmatically Focus on a Form in a Webview (Wkwebview)
Passing Data from App Delegate to View Controller
iOS Keychain Services: Only Specific Values Allowed for Ksecattrgeneric Key