Ios 更改导航返回按钮的目的地

Ios 更改导航返回按钮的目的地,ios,swift,uiviewcontroller,xcode6,uinavigationbar,Ios,Swift,Uiviewcontroller,Xcode6,Uinavigationbar,如何更改默认导航返回按钮所指向的视图控制器?“后退”按钮通常会将您带回上一个视图控制器。但是如果我想让它通过两个视图控制器返回呢?我的意思是,我想更改“后退”按钮所指向的视图控制器。我不喜欢创建自定义后退按钮。那么还有别的办法吗?可能是链接到“后退”按钮或其他什么的展开序列?您可以通过添加这样的自定义后退按钮来完成此操作。在导航栏的点击后退按钮上添加自定义操作处理程序 + (void)addCustomBackButtonForController:(id <MyCustomBackBut

如何更改默认导航返回按钮所指向的视图控制器?“后退”按钮通常会将您带回上一个视图控制器。但是如果我想让它通过两个视图控制器返回呢?我的意思是,我想更改“后退”按钮所指向的视图控制器。我不喜欢创建自定义后退按钮。那么还有别的办法吗?可能是链接到“后退”按钮或其他什么的展开序列?

您可以通过添加这样的自定义后退按钮来完成此操作。在导航栏的点击后退按钮上添加自定义操作处理程序

+ (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;
    }
}
+(void)添加控制器:(id)iViewController的自定义BackButton,在vController中使用导航栏:(UINavigationController*),在VITEM中使用导航项:(UINavigationItem*){
如果([self isIOS7orAbove]){
UIImage*反箭头=[UIImage ImageName:kMyIOS7BackButtonImage];
UIButton*aBackButton=[UIButton Button类型:UIButtonTypeSystem];
CGSize ABackButtonExtSize=[MyLocalizedBackButton sizeWithFont:[UIFont systemFontOfSize:17.0]];
aBackButton.frame=CGRectMake(0.0,0.0,abackbuttonextsize.width+backArrow.size.width,iNavController.navigationBar.frame.size.height);
aBackButton.contentHorizontalAlignment=uicontrol内容HorizontalAlignment左侧;
SEL backSelector=NSSelectorFromString(@“backAction”);
[后退按钮添加目标:iViewController操作:ControlEvents的后退选择器:UIControlEventTouchUpInside];
[aBackButton设置标题:MyLocalizedBackButton for状态:UIControlStateNormal];
[aBackButton设置图像:状态的反箭头:UIControlStateNormal];
[aBackButton setExclusiveTouch:是];
如果([self isIOS7orAbove]){
aBackButton.titleLabel.font=[UIFont systemFontOfSize:17.0];
}否则{
aBackButton.titleLabel.font=[UIFont boldSystemFontOfSize:12.0];
}
UIBarButtonItem*aLeftBarButtonItem=[[UIBarButtonItem alloc]initWithCustomView:aBackButton];
UIBarButtonItem*aNegativeSpacer=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace目标:nil操作:nil];
aNegativeSpacer.width=kmyios7barbuttonegativespacer宽度;
iNavItem.leftBarButtonItems=@[aNegativeSpacer,aLeftBarButtonItem];
}否则{
UIButton*aCustomBackButton=[UIButton Button类型:101];
SEL backSelector=NSSelectorFromString(@“backAction”);
[aCustomBackButton添加目标:iViewController操作:控制事件的后退选择器:UIControlEventTouchUpInside];
[aCustomBackButton设置标题:MyLocalizedBackButton for状态:uicontrol状态正常];
[aCustomBackButton设置排他性触摸:是];
如果([self isIOS7orAbove]){
aCustomBackButton.titleLabel.font=[UIFont systemFontOfSize:kFontSize17];
}否则{
aCustomBackButton.titleLabel.font=[UIFont boldSystemFontOfSize:kFontSize12];
}
UIBarButtonItem*aLeftBarButtonItem=[[UIBarButtonItem alloc]initWithCustomView:aCustomBackButton];
iNavItem.leftBarButtonItem=aLeftBarButtonItem;
}
}

您可以覆盖
willMoveToParentViewController
。在容器视图控制器(如
UINavigationController
)中添加或删除视图控制器之前,会调用此方法。添加时,
parent
参数包含容器视图控制器,删除时,
parent
参数为nil

此时,可以删除导航堆栈中倒数第二个视图控制器(无动画),如下所示:

目标-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];
        }
    }
}
Swift

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参数多次调用。例如,如果您尝试使用边缘擦除来弹出视图控制器,但在中间中止,则每次尝试时都会调用该方法。确保添加额外的检查,以确保删除的视图控制器不会超过所需数量。

实现所需行为的最简单方法可能是使用
navigationController.SetViewController(控制器,动画:true)

如果要从控制器A返回2个控制器,而不是仅返回一个,请在显示以下内容时使用此自定义序列:

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设置自定义类的精彩教程:

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

extension UINavigationController {
    func replaceCurrentViewControllerWith(viewController: UIViewController, animated: Bool) {
        var controllers = viewControllers
        controllers.removeLast()
        controllers.append(viewController)
        setViewControllers(controllers, animated: animated)
    }
}
然后只需使用self.navigationController!。将CurrentViewControllerWith(newController,动画:true)替换为self.navigationControllerPushViewController(newController,动画:true)


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

这可能只是重复上面所说的,但我通过在上一个VewController中修改viewDidLoad解决了这个问题。“控制器”是UIViewController类型的数组。在我的例子中,我只想回到根视图控制器,因此数组只包含根视图控制器(第一个)和当前视图控制器(最后一个)。然后“SetViewController”将当前堆栈替换为我创建的堆栈

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)
}

“但是如果我想让它通过两个视图控制器返回”是什么意思?@CalebKleveter我的意思是如果我想转到另一个视图控制器而不是上一个视图控制器,该怎么办?我想在没有自定义后退按钮的情况下实现这一点,否则我将无法向后滑动,后退动画将丢失。很多应用程序都能够实现这一点,而无需自定义后退按钮。有什么办法我也可以这样做吗?你说的不能向后滑动和向后动画将丢失是什么意思?你知道吗