2011-08-10 17 views
75

में पिछले दृश्य नियंत्रक की पहचान करनी 2 अलग navigationcontrollers, RootViewController एक के साथ एक और RootViewController बीमैं कैसे नेविगेशन ढेर

के साथ अन्य मैं या तो ए या बी के नेविगेशन ढेर पर ViewController सी पुश करने के लिए कर रहा हूँ।

प्रश्न: जब मैं ViewController सी में हूं, तो मैं कैसे पता लगा सकता हूं कि मैं ए या बी के ढेर में हूं या नहीं?

+7

क्यों सिर्फ सी पर एक previousViewController संपत्ति है कि आप निर्धारित करते हैं सी धक्का नहीं बना? या जब आप इसे दबाते हैं तो सी को ए या बी से इसकी आवश्यकता होती है? –

+1

@TerryWilcox, 'आज संबंध बहुत जटिल हो सकते हैं – Vyacheslav

उत्तर

105

आप UINavigationController के viewControllers संपत्ति इस्तेमाल कर सकते हैं:

@property(nonatomic, copy) NSArray *viewControllers

चर्चा: रूट दृश्य नियंत्रक सरणी में सूचकांक 0 पर है, वापस दृश्य नियंत्रक सूचकांक n-2 पर है, और शीर्ष नियंत्रक इंडेक्स एन -1 पर है, जहां एन सरणी में आइटम की संख्या है।

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

आप इस्तेमाल कर सकते हैं कि परीक्षण करने के लिए है कि क्या रूट दृश्य नियंत्रक (सरणी सूचकांक 0 में एक) दृश्य नियंत्रक एक है या बी

+0

मैं इसे स्विफ्ट में एक स्ट्रिंग के रूप में कैसे प्राप्त कर सकता हूं .. (मैं तेज़ी से नया हूं) –

+0

@cyberboy जितना आसान है:' var viewControllers: [UIViewController] ' – NerdyTherapist

+1

पिछला दृश्य नियंत्रक 'viewControllers.last' – Burak

1

उपयोग इसे पुनः प्राप्त करने navigationController विधि। documentation on Apple's site देखें।

navigationController एक माता पिता या पूर्वज एक नेविगेशन नियंत्रक है। (रीड-ओनली)

@property (nonatomic, केवल पढ़ने के लिए, को बनाए रखने) UINavigationController * navigationController

चर्चा केवल एक नेविगेशन नियंत्रक वापस लौट आता है दृश्य नियंत्रक अपने ढेर में है। यह संपत्ति शून्य है यदि नेविगेशन नियंत्रक नहीं मिल सकता है।

उपलब्धता आईओएस 2.0 और बाद में उपलब्ध है।

3

पहुँच viewControllers संपत्ति के n-2 तत्व जनक दृश्य नियंत्रक का उपयोग करने की।

एक बार आपके पास यह उदाहरण हो जाने के बाद, आप NSStringFromClass() फ़ंक्शन से बाहर आने वाले लॉगिंग करके अपना प्रकार जांच सकते हैं। या आप नियंत्रक ए और बी में कुछ static const पहचानकर्ता स्ट्रिंग रख सकते हैं, और एक गेटर फ़ंक्शन जो स्ट्रिंग को प्रिंट करता है।

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

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

पर एक दृश्य नियंत्रक की वर्तमान अनुक्रमणिका प्राप्त करने का कोई आसान तरीका होगा या मैं अपने पदानुक्रम संरचना के आधार पर उन्हें हार्डकोड कर दूंगा। – HpTerm

100

यहाँ स्वीकार किए जाते हैं जवाब के कार्यान्वयन है

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

यह सही "वापस दृश्य नियंत्रक" जहां वर्तमान की परवाह किए बिना वापस आ जाएगी कक्षा नेविगेशन ढेर पर है।

+20

मैं इसे 'UIViewController' – MaxGabriel

11

स्वीकार किए जाते हैं जवाब का एक अधिक सामान्य कार्यान्वयन:

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

पर एक श्रेणी के रूप में जोड़ने की अनुशंसा करता हूं, मैं इसे एक स्ट्रिंग के रूप में कैसे प्राप्त कर सकता हूं .. (मैं तेज़ी से नया हूं) –

+0

@cyberboy हाय! मुझे यकीन नहीं है कि मैं आपका प्रश्न समझता हूं। क्या आप बैक व्यू कंट्रोलर विवरण को स्ट्रिंग के रूप में प्राप्त करना चाहते हैं? यदि ऐसा है, तो आप 'println ("backViewController है: \ (backViewController' पर विचार कर सकते हैं।विवरण) ")'; यह आपको "UINavigationController: 0x7fcea1d286b0" जैसा विवरण देगा, जो बहुत स्पष्ट नहीं है लेकिन कम से कम आपको ऑब्जेक्ट की पहचान करने की अनुमति देता है। जैसा कि मैंने कहा था, मुझे यकीन नहीं है कि आपको वास्तव में क्या चाहिए .. – cdf1982

0

खोजें पिछले दृश्य नियंत्रक सरल है।

आपके मामले में, यानी, आप सी में हैं और आपको बी, [self.navigationController.viewControllers lastObject] की आवश्यकता है जो आप चाहते हैं।

ए के लिए, चूंकि ए रूट व्यू कंट्रोलर है, तो आप lastObject को firstObject से प्राप्त करने के लिए प्रतिस्थापित कर सकते हैं।

+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

मैंने इस कोड का एक संशोधित संस्करण पोस्ट किया है जिसमें स्विफ्ट 3 का समर्थन एक नए उत्तर के रूप में है। – Cin316

0

कार्यान्वयन स्विफ्ट 2.2 के लिए - एक UIViewController विस्तार में इस जोड़े। अर्थ में सुरक्षित यह nil लौटाएगा यदि व्यू कंट्रोलर रूटवैक है या नेविगेशन कंट्रोलर में नहीं है।

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

यहाँ Prabhu Beeman's स्विफ्ट कोड यह स्विफ्ट 3 समर्थन करने के लिए adapts इस बात का एक modifed संस्करण है।

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

कुछ नोट्स: रिवर्स() अब उलट दिया गया है() और self.navigationController ?viewControllers कभी "स्वयं" दृश्य नियंत्रक नहीं होता है, इसलिए stack.last वापस लौटें पर्याप्त होना चाहिए – Kappe

0
स्विफ्ट गार्ड का उपयोग कर के साथ

:

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

के लिए तेजी से 3 आप यह कर सकते हैं:

var backtoViewController:UIViewController! 
for viewController in (self.navigationController?.viewControllers)!.reversed() { 
    if viewController is NameOfMyDestinationViewController { 
      backtoViewController = viewController 
    } 
} 
self.navigationController!.popToViewController(backtoViewController, animated: true) 

आपको केवल नियंत्रक द्वारा "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] 
    } 
} 
संबंधित मुद्दे