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

佐手、 提交于 2019-12-10 20:47:16

问题


I have a UIViewController called 'detailViewController'.

This view controller is accessed through multiple different segues using the push 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).

How do I do this?

I have tried changing the segue types however that didn't really do anything at all.

Peter


回答1:


The method you're looking for is UINavigationController's 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:

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



回答2:


If the masterViewController you're talking about is the root you can call:

[self.navigationController popToRootViewControllerAnimated:YES];



回答3:


You can create the back button yourself and call [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;



回答4:


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.




回答5:


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];


来源:https://stackoverflow.com/questions/22076066/how-do-i-manually-set-the-back-destination-in-ios-apps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!