如何在 iOS 应用程序中手动设置“返回”目的地
Posted
技术标签:
【中文标题】如何在 iOS 应用程序中手动设置“返回”目的地【英文标题】:How do I manually set the "Back" destination in iOS apps 【发布时间】:2014-02-27 17:36:22 【问题描述】:我有一个名为“detailViewController”的 UIViewController。
使用 push segue 通过多个不同的 segue 访问此视图控制器。
我面临的问题是 detailViewController 上的后退按钮将用户带回到前一个视图控制器(应该如此),但是我希望后退按钮将用户带到 masterViewController(默认 UIViewController 在应用程序)。
我该怎么做?
我尝试过更改 segue 类型,但实际上并没有做任何事情。
彼得
【问题讨论】:
如果您不想回到导航控制器的根目录,请澄清您的问题。不清楚你在问什么。例如,masterViewController
与您的 detailViewController
有什么关系?
【参考方案1】:
你要找的方法是 UINavigationController 的popToRootViewControllerAnimated:
来自documentation:“弹出堆栈中除根视图控制器之外的所有视图控制器并更新显示。”
您需要创建一个自定义后退按钮。您不能 afaik 覆盖后退按钮的功能。
比如:
UIButton *myBackButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myBackButton addTarget:self action:@selector(popToRoot:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *myCustomBackButtonItem = [[UIBarButtonItem alloc] initWithCustomView:myBackButton];
[self.navigationItem setLeftBarButtonItem:myCustomBackButtonItem];
然后 popToRoot: 的实现如下所示:
- (void)popToRoot:(id)sender
[self.navigationController popToRootViewControllerAnimated:YES];
【讨论】:
在尝试您的代码时出现两个错误:未声明的选择器 popUpRoute 和“UIButton”没有可见的@interface 声明选择器“addTarget:selector:forControlEvent:” 谢谢。我是随意的。现在已经修好了。由你来实现 popToRoot:。我将包括示例实现。 那太好了,我试试看:) 最后一个问题,如何在按钮上设置文字?现在完全是空白? 你会想要 UIButton 的 setTitle:forState:.【参考方案2】:如果您所说的masterViewController
是您可以调用的根:
[self.navigationController popToRootViewControllerAnimated:YES];
【讨论】:
【参考方案3】:您可以自己创建后退按钮并致电[self.navigationController popToRootViewControllerAnimated:YES]
。但是,这确实需要您自己创建后退按钮。另一种选择是获取当前视图控制器,并删除除第一个和当前视图控制器之外的所有视图控制器:
NSMutableArray *viewControllers = [self.navigationController.viewControllers mutableCopy];
[viewControllers removeObjectsInRange:NSRangeMake(1, [viewControllers count] - 2)];
self.navigationController.viewControllers = viewControllers;
【讨论】:
【参考方案4】:使用以下代码返回主视图控制器:
[self.navigationController popViewControllerAnimated:YES];
编辑: 基于 cmets,我意识到我的代码只会让您后退一步,并且可能无法回答这个问题中的问题。谢谢。
【讨论】:
实际上这只是在您的导航堆栈中退了一步...也许可以尝试 [self.navigationController popToRootViewControllerAnimated:NO]; 让我知道你为什么不赞成我的回答。如果你有一个导航控制器,它就可以工作。 他们都没有工作。第一个建议只是更新了导航栏。您建议在加载 detailVC 时对其进行更新 @Mushin,如果用户有 4 个视图控制器被推送到导航控制器上怎么办?这只会将它们带回一次,而不是返回根目录。【参考方案5】:我想出了一个解决方法,它在导航控制器的集合中查找并使用目标控制器的名称查找现有控制器和目标控制器之间的偏移量,并删除中间控制器。不确定它是否接近您的需求,但请尝试一下:
- (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;
并在一些基本控制器中定义它:
-(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];
这是怎么称呼的:
[self popToViewController:@"NameOfDestinationControllerInNavStack" withControllers:self.navigationController];
【讨论】:
您的代码有错误,我不确定在哪里放置一些代码? 如果启用 arc 进行编译,您可能会遇到非 arc 错误。删除所有有release
调用的行。创建一个 BaseViewController :UIViewController 并继承所有 UIViewControllers 如下:detailViewController : BaseViewController
将前两个 sn-p 放在 base 中,第三个放在 detailViewController
中。以上是关于如何在 iOS 应用程序中手动设置“返回”目的地的主要内容,如果未能解决你的问题,请参考以下文章