如何更改默认导航后退按钮带我到的视图控制器?后退按钮通常会将您带回到上一个视图控制器。但是如果我想让它由两个视图控制器返回呢?我的意思是我想改变后退按钮带我到的视图控制器。我不喜欢创建自定义后退按钮。还有其他方法吗?可能是一个与后退按钮或其他东西相关联的展开segue?
答案 0 :(得分:8)
实现所需行为的最简单方法是使用navigationController.setViewControllers(controllers, animated: true)
。
如果您想从控制器A返回2个控制器而不是只有一个,请在演示A时使用此自定义segue:
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)
}
}
}
这是一个很好的教程,如何在Interface Builder中为您的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)
。
可以轻松调整此代码以删除所需的控制器。
答案 1 :(得分:7)
您可以覆盖willMoveToParentViewController
。在将视图控制器添加到容器视图控制器中或从容器视图控制器中删除之前调用此方法(如UINavigationController
)。添加时,parent
参数包含容器视图控制器,当删除它时,parent
参数为零。
此时你可以删除(没有动画)导航堆栈中的倒数第二个视图控制器,如下所示:
<强>目标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)
}
}
}
}
您还可以删除多个或添加新的。只需确保在完成后,您的数组包含至少2个视图控制器,其中最后一个不变(最后一个是被删除的,并且在调用此方法后将自动从数组中删除)。
另请注意,使用nil参数可以多次调用此方法。例如,如果您尝试使用边缘滑动弹出视图控制器但在中间中止,则每次尝试时都会调用该方法。请务必添加其他检查,以确保您不会删除比您想要的更多的视图控制器。
答案 2 :(得分:1)
这可能只是重复上面所说的,但我通过在最后一个VewController中修改viewDidLoad来解决这个问题。 “theControllers”是一个UIViewController类型的数组。在我的例子中,我只想回到根视图控制器,因此数组只包含根视图控制器(第一个)和当前视图控制器(最后一个)。然后“setViewControllers”将当前堆栈替换为我创建的堆栈。
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)
}
答案 3 :(得分:0)
您可以通过添加这样的自定义后退按钮来完成此操作。在导航栏上的“后退”按钮上添加自定义操作处理程序。
+ (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;
}
}