更改导航上一步button的目的地

如何更改视图控制器的默认导航后退button带我到? 后退button通常会将您带回到先前的视图控制器。 但是如果我想让它回到两个视图控制器呢? 我的意思是我想改变视图控制器的后退button带我。 我不喜欢创build一个自定义后退button。 那还有别的办法吗? 可能是一个放松的继续链接到后退button什么的?

可能最简单的方法来实现你想要的行为是使用navigationController.setViewControllers(controllers, animated: true)

如果你想从控制器A而不是仅仅一个控制器返回2个控制器,当呈现A时使用这个自定义的继续:

 class ReplaceControllerSegue: UIStoryboardSegue { override func perform() { if let navigationController = sourceViewController.navigationController as UINavigationController? { var controllers = navigationController.viewControllers controllers.removeLast() controllers.append(destinationViewController) navigationController.setViewControllers(controllers, animated: true) } } } 

这里是不错的教程如何在界面生成器中为您的segue设置自定义类: http : //blog.jimjh.com/a-short-tutorial-on-custom-storyboard-segues.html

如果您通过代码呈现控制器,请使用以下类别:

 extension UINavigationController { func replaceCurrentViewControllerWith(viewController: UIViewController, animated: Bool) { var controllers = viewControllers controllers.removeLast() controllers.append(viewController) setViewControllers(controllers, animated: animated) } } 

然后使用self.navigationController!.replaceCurrentViewControllerWith(newController, animated: true)而不是self.navigationControllerPushViewController(newController, animated: true)

调整这个代码很容易,可以根据需要去除尽可能多的控制器。

您可以覆盖willMoveToParentViewController 。 在视图控制器添加到容器视图控制器中或从容器视图控制器中移除之前调用此方法(如UINavigationController )。 当它被添加时, parent参数包含容器视图控制器,当它被移除时, parent参数是nil。

在这一点上,你可以删除(没有animation)导航堆栈中倒数第二个视图控制器,如下所示:

Objective-C的

 - (void)willMoveToParentViewController:(UIViewController *)parent { [super willMoveToParentViewController:parent]; if (parent == nil) { NSArray *viewControllers = self.navigationController.viewControllers; NSUInteger viewControllersCount = viewControllers.count; if (viewControllersCount > 2) { NSMutableArray *mutableViewControllers = [NSMutableArray arrayWithArray:viewControllers]; [mutableViewControllers removeObjectAtIndex:(viewControllersCount - 2)]; [self.navigationController setViewControllers:[NSArray arrayWithArray:mutableViewControllers] animated:NO]; } } } 

迅速

 override func willMoveToParentViewController(parent:UIViewController?) { super.willMoveToParentViewController(parent) if (parent == nil) { if let navigationController = self.navigationController { var viewControllers = navigationController.viewControllers var viewControllersCount = viewControllers.count if (viewControllersCount > 2) { viewControllers.removeAtIndex(viewControllersCount - 2) navigationController.setViewControllers(viewControllers, animated:false) } } } } 

您也可以删除多个或添加新的。 只要确保完成后,数组至less包含两个视图控制器,最后一个视图控制器不变(最后一个是被删除的视图控制器,调用此方法后将自动从数组中移除)。

还要注意的是,这个方法可以用一个nil参数多次调用。 例如,如果您尝试使用边缘滑动popup视图控制器,但在中间放弃,则每次尝试时都会调用该方法。 一定要添加额外的检查,以确保您不会删除比您想要的更多的视图控制器。

你可以通过添加一个像这样的自定义后退button来实现。 点击导航栏上的“返回”button,添加您的自定义操作处理程序。

 + (void)addCustomBackButtonForController:(id <MyCustomBackButtonDelegate>)iViewController withNavBar:(UINavigationController *)iNavController andNavItem:(UINavigationItem *)iNavItem { if ([self isIOS7orAbove]) { UIImage *backArrow = [UIImage imageNamed:kMyIOS7BackButtonImage]; UIButton *aBackButton = [UIButton buttonWithType:UIButtonTypeSystem]; CGSize aBackButtonTextSize = [MyLocalizedBackButton sizeWithFont:[UIFont systemFontOfSize:17.0]]; aBackButton.frame = CGRectMake(0.0, 0.0, aBackButtonTextSize.width + backArrow.size.width, iNavController.navigationBar.frame.size.height); aBackButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; SEL backSelector = NSSelectorFromString(@"backAction"); [aBackButton addTarget:iViewController action:backSelector forControlEvents:UIControlEventTouchUpInside]; [aBackButton setTitle:MyLocalizedBackButton forState:UIControlStateNormal]; [aBackButton setImage:backArrow forState:UIControlStateNormal]; [aBackButton setExclusiveTouch:YES]; if ([self isIOS7orAbove]) { aBackButton.titleLabel.font = [UIFont systemFontOfSize:17.0]; } else { aBackButton.titleLabel.font = [UIFont boldSystemFontOfSize:12.0]; } UIBarButtonItem *aLeftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:aBackButton]; UIBarButtonItem *aNegativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; aNegativeSpacer.width = kMyIOS7BarButtonNegativeSpacerWidth; iNavItem.leftBarButtonItems = @[aNegativeSpacer, aLeftBarButtonItem]; } else { UIButton *aCustomBackButton = [UIButton buttonWithType:101]; SEL backSelector = NSSelectorFromString(@"backAction"); [aCustomBackButton addTarget:iViewController action:backSelector forControlEvents:UIControlEventTouchUpInside]; [aCustomBackButton setTitle:MyLocalizedBackButton forState:UIControlStateNormal]; [aCustomBackButton setExclusiveTouch:YES]; if ([self isIOS7orAbove]) { aCustomBackButton.titleLabel.font = [UIFont systemFontOfSize:kFontSize17]; } else { aCustomBackButton.titleLabel.font = [UIFont boldSystemFontOfSize:kFontSize12]; } UIBarButtonItem *aLeftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:aCustomBackButton]; iNavItem.leftBarButtonItem = aLeftBarButtonItem; } } 

这可能只是重复了上面所说的,但我通过修改最后一个VewController中的viewDidLoad来解决这个问题。 “theControllers”是一个UIViewControllertypes的数组。 在我的情况下,我只想回到根视图控制器,所以数组只包含根视图控制器(第一个)和当前视图控制器(最后一个)。 然后“setViewControllers”用我创build的那个replace当前的堆栈。

 override func viewDidLoad() { super.viewDidLoad() var theControllers = [UIViewController]() theControllers.append(self.navigationController!.viewControllers.first!) theControllers.append(self.navigationController!.viewControllers.last!) self.navigationController?.setViewControllers(theControllers, animated: false) }