How to perform segue inside unwind function

2019-08-14 05:46发布

问题:

I have 3 MVCs and name them A, B, C here.

A is the main MVC with a button "Menu" connected to B with popover segue.

A also connected to C with a manual show segue.

B is a popover MVC with a button "Detail" connected to A with unwind segue.

C is the detail MVC with detail info.

Inside the unwind function of A. I call performSegueWithIdentifier to show C.


Expected behavior is

  • Click "Detail" button in B
  • B disappear and A show up
  • C show up

But running the app I got.

  • Click "Detail" button in B
  • B disappear and A show up
  • C show up
  • C disappear and A show up

C show up and disappear suddenly which is not what I want.


Some additional info

  • Popover B is needed for more buttons.
  • A is embeded in a UINavigationController. Connecting A -> C rather than B -> C, for a Back button on top of C.

回答1:

Seems unwind function is not the correct place to call performSegueWithIdentifier.

UIKit will pop view controller after calling the unwind function.

Thus push new view controller inside unwind function will pop quickly.

The solution is to delay performSegueWithIdentifier.

Solution 1: NOT WORKING FINE

Adding an bool instance and inside viewDidAppear use this instance to determine if we perform segue.

Won't work if B controller is a popover. After B popover disappear, viewDidAppear is not called for A controller.

Solution 2: WORKING

Push performSegueWithIdentifier into main queue.

@IBAction func unwind(segue : UIStoryboardSegue) {
    dispatch_async(dispatch_get_main_queue()) {
        self.performSegueWithIdentifier("SomeSegue", sender: self)
    }
}


回答2:

you can easily switch between the viewControllers by assigning storyboard id to them using below code ..

// you need to create UIStoryboard object by giving name of your storyboard
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
// here you need to create storyboard ID of perticular view where you need to navigate your app 
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"viewContIdentifire"];

// if use presentViewController this will not enables you to go back to previous view
[self presentViewController:vc animated:NO completion:nil];
                    **// OR**
// using pushViewController lets you to go back to the previous view
[self.navigationController pushViewController:vc animated:YES];

Or still you want to work with segue so must gain control over them by implementing its delegate method below so they perform accordingly.

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"segueName"]) {
        // perform segue
        [self performSegueWithIdentifier:@"SegueIdentifier" sender:self]; 
    }
}

happy coding .. :)