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

前端 未结 14 776
眼角桃花
眼角桃花 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:43

    For this problem, I think the answer is just simple as

    1. Get the array of view controllers from NavigationController
    2. Removing the last ViewController (current view controller)
    3. Insert a new one at last
    4. Then set the array of ViewControllers back to the navigationController as bellow:

       if let navController = self.navigationController {
          let newVC = DestinationViewController(nibName: "DestinationViewController", bundle: nil)
      
          var stack = navController.viewControllers
          stack.remove(at: stack.count - 1)       // remove current VC
          stack.insert(newVC, at: stack.count) // add the new one
          navController.setViewControllers(stack, animated: true) // boom!
       }
      

    works perfectly with Swift 3.

    Hope it helps for some new guys.

    Cheers.

    0 讨论(0)
  • As mentioned in previous answers to pop not animated and then to push animated won't look very good because user will see the actual process. I recommend you first push animated and then remove the previous vc. Like so:

    extension UINavigationController {
        func replaceCurrentViewController(with viewController: UIViewController, animated: Bool) {
            pushViewController(viewController, animated: animated)
            let indexToRemove = viewControllers.count - 2
            if indexToRemove >= 0 {
                viewControllers.remove(at: indexToRemove)
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 02:45

    How about this :) I now it's old question, but this will work as a charm:

    UIViewController *destinationController = [[UIViewController alloc] init];
    UINavigationController *newNavigation = [[UINavigationController alloc] init];
    [newNavigation setViewControllers:@[destinationController]];
    [[[UIApplication sharedApplication] delegate] window].rootViewController = newNavigation;
    
    0 讨论(0)
  • 2020-11-28 02:46

    This worked for me in Swift 3:

    class ReplaceSegue: UIStoryboardSegue {
        override func perform() {
            if let navVC = source.navigationController {
                navVC.pushViewController(destination, animated: true)
            } else {
                super.perform()
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-28 02:47

    Use below code last view controller You can use other button or put it your own instead of cancel button i have used

    - (void)viewDidLoad
    {
     [super viewDidLoad];
    
     [self.navigationController setNavigationBarHidden:YES];
    
     UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(dismiss:)];
    
    self.navigationItemSetting.leftBarButtonItem = cancelButton;
    
    }
    
    - (IBAction)dismissSettings:(id)sender
    {
    
    // your logout code for social media selected
    [self.navigationController popToRootViewControllerAnimated:YES];
    
    }
    
    0 讨论(0)
  • 2020-11-28 02:49

    You could use a custom segue: to do it you need to create a class subclassing UIStoryboardSegue (example MyCustomSegue), and then you can override the "perform" with something like this

    -(void)perform {
        UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
        UIViewController *destinationController = (UIViewController*)[self destinationViewController];
        UINavigationController *navigationController = sourceViewController.navigationController;
        // Pop to root view controller (not animated) before pushing
        [navigationController popToRootViewControllerAnimated:NO];
        [navigationController pushViewController:destinationController animated:YES];    
    }
    

    At this point go to Interface Builder, select "custom" segue, and put the name of your class (example MyCustomSegue)

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