简体   繁体   English

如何在iOS应用程序中手动设置“返回”目标

[英]How do I manually set the “Back” destination in iOS apps

I have a UIViewController called 'detailViewController'. 我有一个名为'detailViewController'的UIViewController。

This view controller is accessed through multiple different segues using the push segue. 使用推送segue通过多个不同的段访问该视图控制器。

The problem I am facing is that the back button on the detailViewController takes the user back to the previous view controller (as it should), however I would like the back button to take the user to the masterViewController (the default UIViewController in the app). 我面临的问题是detailViewController上的后退按钮将用户带回到前一个视图控制器(应该如此),但我希望后退按钮将用户带到masterViewController(应用程序中的默认UIViewController) 。

How do I do this? 我该怎么做呢?

I have tried changing the segue types however that didn't really do anything at all. 我已经尝试过更改segue类型但是根本没有做任何事情。

Peter 彼得

The method you're looking for is UINavigationController's popToRootViewControllerAnimated: 您正在寻找的方法是UINavigationController的popToRootViewControllerAnimated:

From the documentation : "Pops all the view controllers on the stack except the root view controller and updates the display." 文档 :“弹出除根视图控制器之外的堆栈上的所有视图控制器并更新显示。”

You'll need to create a custom back button. 您需要创建自定义后退按钮。 You can't afaik override the back button's functionality. 你不能忽略后退按钮的功能。

So something like: 所以类似于:

UIButton *myBackButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myBackButton addTarget:self action:@selector(popToRoot:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *myCustomBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:myBackButton];
[self.navigationItem setLeftBarButtonItem:myCustomBackButtonItem];

and then the implementation of popToRoot: would look like: 然后popToRoot的实现:看起来像:

- (void)popToRoot:(id)sender
{
    [self.navigationController popToRootViewControllerAnimated:YES];
}

Use the following code in order to go back to main view controller: 使用以下代码返回主视图控制器:

[self.navigationController popViewControllerAnimated:YES];

Edit: Based on the comments, I realize that my code takes you only one step back and may not answer what is asked in this question. 编辑:根据评论,我意识到我的代码只带你退一步,可能无法回答这个问题中的问题。 Thanks. 谢谢。

如果你正在谈论的masterViewController是你可以调用的root:

[self.navigationController popToRootViewControllerAnimated:YES];

You can create the back button yourself and call [self.navigationController popToRootViewControllerAnimated:YES] . 您可以自己创建后退按钮并调用[self.navigationController popToRootViewControllerAnimated:YES] However, that does require you to create the back button yourself. 但是,这确实需要您自己创建后退按钮。 An alternative option could be to take the current view controller, and remove all of them except the first and current ones: 另一种选择可以是获取当前视图控制器,并删除除第一个和当前视图控制器之外的所有视图控制器:

NSMutableArray *viewControllers = [self.navigationController.viewControllers mutableCopy];
[viewControllers removeObjectsInRange:NSRangeMake(1, [viewControllers count] - 2)];
self.navigationController.viewControllers = viewControllers;

I came up with a workaround that looks up in a navigation controller's collection and find the offset between the existing and destination controller using name of destination controller and remove the in-between controller. 我想出了一个在导航控制器集合中查找的解决方法,并使用目标控制器的名称查找现有控制器和目标控制器之间的偏移量,并删除中间控制器。 Not sure if it is close to your need but give it a try: 不确定它是否接近你的需要,但尝试一下:

- (NSArray *)navigateToViewController:(NSString *)destinationControllerName withControllers:(NSArray *)sourceControllers
{
    NSMutableArray *controllers = [[NSMutableArray alloc] initWithArray:sourceControllers];

    NSInteger sourceControllerIndex = [controllers count] - 1;  // Value should be index oriented instead of position oriented.
    NSInteger destControllerIndex = 0;

    // Find position of destination controller  (index oriented)
    for (UIViewController *controller in controllers)
    {
        NSString *controllerName = NSStringFromClass([controller class]);
        NSLog(@"class name: %@", controllerName);

        if([[controllerName lowercaseString] isEqualToString:[destinationControllerName lowercaseString]])
            break;

        destControllerIndex +=1;
    }

    // If desired controller does not exists in the stack, do not proceed.
    if (destControllerIndex == sourceControllerIndex)
    {
        return controllers;
    }
    // If destination is the same as source do not enter in this block
    // If destination and source controllers have zero or no controllers in between do not enter in this block
    // If destination and source controllers has few controllers (at least one) in between, go inside this block.
    // Here "destControllerIndex + 1" shows, there is at least one controller in between source and destination.
    else if(destControllerIndex + 1 < sourceControllerIndex)
    {
        NSLog(@"controllers in stack: %@", controllers);

        // Start from the controller following the source controller in stack and remove it
        // till the destination controller arrives
        for (NSInteger iterator = sourceControllerIndex - 1; iterator > destControllerIndex; iterator--)
        {
            UIViewController *cont = [controllers objectAtIndex:iterator];
            if(cont) {
            [cont release]; cont = nil; }
            [controllers removeObjectAtIndex:iterator];
            NSLog(@"controllers in stack: %@", controllers);
        }
    }

    return controllers;
}

and define it in some base controller: 并在某个基本控制器中定义它:

-(void) popToViewController:(NSString *)controllerName withNavController:(UINavigationController *)navController
{
    // STStatistics refers a singleton class of common functions.
    NSArray *mArr = [STStatistics navigateToViewController:controllerName withControllers:navController.viewControllers];  

    navController.viewControllers = mArr;

    // There should be more than one controller in stack to pop.
    if([mArr count] > 1)
    {
        [navController popViewControllerAnimated:YES];
    }
}

and here is how called: 以下是如何调用:

[self popToViewController:@"NameOfDestinationControllerInNavStack" withControllers:self.navigationController];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM