我有两个单独的人navigationcontrollers
,一个与RootViewController
A,另一个与RootViewController
B。
我可以将ViewController
C推入A或B的导航堆栈中。
问题:当我在ViewController
C中时,如何确定我是否在属于A或B的堆栈中?
Answers:
您可以使用UINavigationController
的viewControllers
属性:
@property(nonatomic, copy) NSArray *viewControllers
讨论:根视图控制器位于数组的索引0中,后视图控制器位于索引n-2处,顶部控制器位于索引n-1中,其中n是数组中的项数。
https://developer.apple.com/documentation/uikit/uinavigationcontroller
您可以使用它来测试根视图控制器(数组索引为0的那个)是视图控制器A还是B。
var viewControllers: [UIViewController]
viewControllers.last
viewControllers.last
具有当前的视图控制器,为了获得以前的视图控制器,应使用viewControllers[viewControllers.count-2]
这是公认答案的实现:
- (UIViewController *)backViewController
{
NSInteger numberOfViewControllers = self.navigationController.viewControllers.count;
if (numberOfViewControllers < 2)
return nil;
else
return [self.navigationController.viewControllers objectAtIndex:numberOfViewControllers - 2];
}
UIViewController
快速实现tjklemz代码作为扩展:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for(var i=stack.count-1;i>0;--i) {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
这是Prabhu Beeman的Swift代码的修改版本,可对其进行修改以支持Swift 3:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for i in (1..<stack.count).reverse() {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
访问的n-2
元素viewControllers
属性以访问父视图控制器。
拥有该实例后,您可以通过记录该NSStringFromClass()
函数的内容来检查其类型。或者,您可以static const
在控制器A和B中保留一些标识符字符串,并使用输出该字符串的getter函数。
@tjklemz代码的Swift实现:
var backViewController : UIViewController? {
var stack = self.navigationController!.viewControllers as Array
for (var i = stack.count-1 ; i > 0; --i) {
if (stack[i] as UIViewController == self) {
return stack[i-1] as? UIViewController
}
}
return nil
}
println("backViewController is: \(backViewController.description)")
; 这将为您提供类似“ UINavigationController:0x7fcea1d286b0”的描述,该描述不是很清楚,但至少可以识别您的对象。正如我所说,我不确定您到底需要什么...
使用navigationController
方法进行检索。请参阅Apple网站上的文档。
navigationController父级或祖先,它是导航控制器。(只读)
@property(非原子,只读,保留)UINavigationController * navigationController
讨论如果视图控制器在其堆栈中,则仅返回导航控制器。如果找不到导航控制器,则此属性为nil。
可用性在iOS 2.0和更高版本中可用。
因为死马喜欢被殴打:)
- (UIViewController *)previousViewController
{
NSArray *vcStack = self.navigationController.viewControllers;
NSInteger selfIdx = [vcStack indexOfObject:self];
if (vcStack.count < 2 || selfIdx == NSNotFound) { return nil; }
return (UIViewController *)[vcStack objectAtIndex:selfIdx - 1];
}
Swift 2.2的实现-在UIViewController
扩展中添加它。从某种意义上讲,它是安全的,nil
如果viewcontroller是rootvc或不是导航控件中的rootvc ,它将返回。
var previousViewController: UIViewController? {
guard let viewControllers = navigationController?.viewControllers else {
return nil
}
var previous: UIViewController?
for vc in viewControllers{
if vc == self {
break
}
previous = vc
}
return previous
}
借助Swift使用后卫。
extension UIViewController {
func getPreviousViewController() -> UIViewController? {
guard let _ = self.navigationController else {
return nil
}
guard let viewControllers = self.navigationController?.viewControllers else {
return nil
}
guard viewControllers.count >= 2 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
我的扩展,迅速3
extension UIViewController {
var previousViewController: UIViewController? {
guard let controllers = navigationController?.viewControllers, controllers.count > 1 else { return nil }
switch controllers.count {
case 2: return controllers.first
default: return controllers.dropLast(2).first
}
}
}
对于迅速3,您可以执行以下操作:
var backtoViewController:UIViewController!
for viewController in (self.navigationController?.viewControllers)!.reversed() {
if viewController is NameOfMyDestinationViewController {
backtoViewController = viewController
}
}
self.navigationController!.popToViewController(backtoViewController, animated: true)
您只需要用要返回的viewController替换“ NameOfMyDestinationViewController”即可。