2011-08-10 65 views
75

前視圖控制器具有2個獨立的navigationcontrollers,一個具有RootViewController A和與RootViewController B.我如何識別在導航堆棧

其它我能夠推ViewController下向A或B的導航堆棧。

問題:當我在ViewController C,我如何知道我是否屬於A或B堆棧?

+7

爲什麼不只是創建℃的previousViewController屬性,當您按下賬套?或者在推送時向C提供它需要的信息? –

+1

@TerryWilcox,'因爲現在的關係可能非常複雜 – Vyacheslav

回答

105

你可以使用UINavigationControllerviewControllers屬性:

@property(nonatomic, copy) NSArray *viewControllers

討論:根視圖控制器是在索引0處的陣列中,所述後視圖控制器是在索引n-2,頂層控制器處於索引n-1,其中n是陣列中的項目數。

https://developer.apple.com/documentation/uikit/uinavigationcontroller

你可以用它來測試根視圖控制器(一個數組索引0)是否是視圖控制器A或B.

+0

我怎樣才能把它作爲一個字符串在SWIFT中..(我是新來的swift) –

+0

@cyberboy一樣簡單:'var viewControllers:[UIViewController]' – NerdyTherapist

+1

上一個視圖控制器將位於'viewControllers.last' – Burak

1

使用navigationController方法來檢索它。見documentation on Apple's site

navigationController父母或祖先是導航 控制器。 (只讀)

@屬性(非原子,只讀,保留)的UINavigationController * navigationController

討論如果視圖 控制器處於它的堆棧僅返回一個導航控制器。如果找不到導航 控制器,則此屬性爲零。

狀況可用在IOS 2.0和更高。

3

訪問viewControllers屬性的n-2元素以訪問父視圖控制器。

一旦你的情況,你可以通過登錄什麼出來的NSStringFromClass()功能的檢查它的類型。或者你可以保持控制器A和B部分static const標識字符串,並打印出字符串一個getter函數。

+0

獲取視圖控制器的當前索引的任何簡單方法,或者根據我的層次結構對它們進行硬編碼。 – HpTerm

100

這裏是公認的答案的實現:

- (UIViewController *)backViewController 
{ 
    NSInteger numberOfViewControllers = self.navigationController.viewControllers.count; 

    if (numberOfViewControllers < 2) 
     return nil; 
    else 
     return [self.navigationController.viewControllers objectAtIndex:numberOfViewControllers - 2]; 
} 
+20

我建議在'UIViewController'上添加這個類別 – MaxGabriel

11

一個更普遍的實施接受的答案:

- (UIViewController *)backViewController { 
    NSArray * stack = self.navigationController.viewControllers; 

    for (int i=stack.count-1; i > 0; --i) 
     if (stack[i] == self) 
      return stack[i-1]; 

    return nil; 
} 

這將返回正確的「後視圖控制器」無論在哪裏,目前類在導航堆棧上。

27
- (UIViewController *)backViewController 
{ 
    NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self]; 

    if (myIndex != 0 && myIndex != NSNotFound) { 
     return [self.navigationController.viewControllers objectAtIndex:myIndex-1]; 
    } else { 
     return nil; 
    } 
} 
2

斯威夫特實施@tjklemz代碼:

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 
    } 
+0

我怎樣才能得到這個作爲一個字符串..(我是新來的swift) –

+0

@cyberboy嗨!我不確定我瞭解你的問題。你想獲得backViewController描述作爲一個字符串?如果是這樣,你可能會考慮'println(「backViewController是:\(backViewController。描述)「)';這會給你一個像」UINavigationController:0x7fcea1d286b0「這樣的描述,這個描述不是很清楚,但至少可以讓你識別這個對象,正如我所說的,我不確定你需要什麼。 – cdf1982

0

查找以前的視圖控制器是簡單的。

就你而言,即你在C,你需要B,[self.navigationController.viewControllers lastObject]是你想要的。

對於A來說,因爲A是根視圖控制器,所以可以用firstObject來代替lastObject來獲得。

+0

這不是真的 –

1

因爲死馬喜歡捱打:)

- (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]; 
} 
9

迅速落實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 
    } 
} 
+0

我已經發布了這個代碼的修改版本,它具有Swift 3支持,作爲一個新的答案。 – Cin316

0

實現了雨燕2.2 - 在UIViewController擴展添加此。如果視圖控制器是rootvc或不在導航控制器中,則在安全意義上它將返回nil

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

這裏是Prabhu Beeman's銀行代碼,能夠適應它支持斯威夫特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 
    } 
} 
+0

有幾點注意:reverse()現在是reversed()和self.navigationController?.viewControllers從不包含「自我」視圖控制器,所以返回stack.last應該足夠了 – Kappe

0

隨着使用後衛斯威夫特。

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] 
    } 
} 
2

作爲UINavigationController擴展:

extension UINavigationController { 

    func previousViewController() -> UIViewController? { 
     guard viewControllers.count > 1 else { 
      return nil 
     } 
     return viewControllers[viewControllers.count - 2] 
    } 

} 
0

我的擴展,迅速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 
     } 
    } 
} 
0

爲SWIFT 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」即可。

0

更簡潔斯威夫特impementation:

extension UIViewController { 
    var previousViewController: UIViewController? { 
     guard let nav = self.navigationController, 
       let myIdx = nav.viewControllers.index(of: self) else { 
      return nil 
     } 
     return myIdx == 0 ? nil : nav.viewControllers[myIdx-1] 
    } 
}