Instead of push segue how to replace view controller (or remove from navigation stack)?

前端 未结 14 774
眼角桃花
眼角桃花 2020-11-28 01:46

I have a small iPhone app, which uses a navigation controller to display 3 views (here fullscreen):

\"Xcode

相关标签:
14条回答
  • 2020-11-28 02:26

    To expand on the various segues above, this is my solution. It has the following advantages:

    • Can work anywhere in the view stack, not just the top view (not sure if this is realistically ever needed or even technically possible to trigger, but hey it's in there).
    • It doesn't cause a pop OR transition to the previous view controller before displaying the replacement, it just displays the new controller with a natural transition, with the back navigation being to the same back navigation of the source controller.

    Segue Code:

    - (void)perform {
        // Grab Variables for readability
        UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
        UIViewController *destinationController = (UIViewController*)[self destinationViewController];
        UINavigationController *navigationController = sourceViewController.navigationController;
    
        // Get a changeable copy of the stack
        NSMutableArray *controllerStack = [NSMutableArray arrayWithArray:navigationController.viewControllers];
        // Replace the source controller with the destination controller, wherever the source may be
        [controllerStack replaceObjectAtIndex:[controllerStack indexOfObject:sourceViewController] withObject:destinationController];
    
        // Assign the updated stack with animation
        [navigationController setViewControllers:controllerStack animated:YES];
    }
    
    0 讨论(0)
  • 2020-11-28 02:26

    What you should really do is modally present a UINavigationController containing the social network UIViewControllers overtop of your Menu UIViewController (which can be embedded in a UINavigationController if you want). Then, once a user has authenticated, you dismiss the social network UINavigationController, showing your Menu UIViewController again.

    0 讨论(0)
  • 2020-11-28 02:27

    In swift3 create one segue -add identifier -add and set in segue(storyboard) custom storyboard class from cocoatouch file -In custom class override perform()

    override func perform() {
        let sourceViewController = self.source
        let destinationController = self.destination
        let navigationController = sourceViewController.navigationController
        // Pop to root view controller (not animated) before pushing
        if self.identifier == "your identifier"{
        navigationController?.popViewController(animated: false)
        navigationController?.pushViewController(destinationController, animated: true)
        }
        }
    

    -You also have to override one method in your source viewcontroller

      override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
        return false
    }
    
    0 讨论(0)
  • 2020-11-28 02:33

    Here a quick Swift 4/5 solution by creating a custom seque that replaces the (top stack) viewcontroller with the new one (without animation) :

    class SegueNavigationReplaceTop: UIStoryboardSegue {
    
        override func perform () {
            guard let navigationController = source.navigationController else { return }
            navigationController.popViewController(animated: false)
            navigationController.pushViewController(destination, animated: false)
        }
    }
    
    0 讨论(0)
  • The custom segue didn't work for me, as I had a Splash view controller and I wanted to replace it. Since there was just one view controller in the list, the popToRootViewController still left the Splash on the stack. I used the following code to replace the single controller

    -(void)perform {
        UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
        UIViewController *destinationController = (UIViewController*)[self destinationViewController];
        UINavigationController *navigationController = sourceViewController.navigationController;
        [navigationController setViewControllers:@[destinationController] animated:YES];
    }
    

    and now in Swift 4:

    class ReplaceSegue: UIStoryboardSegue {
    
        override func perform() {
            source.navigationController?.setViewControllers([destination], animated: true)
        }
    }
    

    and now in Swift 2.0

    class ReplaceSegue: UIStoryboardSegue {
    
        override func perform() {
            sourceViewController.navigationController?.setViewControllers([destinationViewController], animated: true)
        }
    }
    
    0 讨论(0)
  • 2020-11-28 02:42

    Well, what you can also do is to use the unwind view controller stuff.

    Actually I think that this is exactly what you need.

    Check this entry: What are Unwind segues for and how do you use them?

    0 讨论(0)
提交回复
热议问题