नेविगेशन स्टैक में पिछले व्यू कंट्रोलर की पहचान कैसे करें


78

मेरे पास 2 अलग हैं navigationcontrollers, एक RootViewControllerए के साथ और दूसरा RootViewControllerबी के साथ ।

मैं ViewControllerC को A या B के नेविगेशन स्टैक पर पुश करने में सक्षम हूं ।

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


7
सी पर एक पिछली ViewController संपत्ति क्यों नहीं बनाते हैं जिसे आप C को धक्का देते समय सेट करते हैं? या जब आप इसे धक्का देते हैं तो ए या बी से इसकी आवश्यकता की जानकारी दें?
टेरी विलकॉक्स

1
@TerryWilcox, 'क्योंकि संबंधों बहुत आजकल जटिल हो सकता है
व्याचेस्लाव

जवाबों:


107

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

@property(nonatomic, copy) NSArray *viewControllers

चर्चा: रूट व्यू कंट्रोलर सरणी में इंडेक्स 0 पर है, बैक व्यू कंट्रोलर इंडेक्स एन -2 पर है, और टॉप कंट्रोलर इंडेक्स एन -1 पर है, जहां एन सरणी में आइटमों की संख्या है।

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

आप यह देखने के लिए उपयोग कर सकते हैं कि रूट व्यू कंट्रोलर (एरे इंडेक्स 0 पर एक) कंट्रोलर ए या बी है या नहीं।


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

@ बर्बर बस के रूप में आसान:var viewControllers: [UIViewController]
NerdyTherapist

1
पिछला दृश्य नियंत्रक पर होगाviewControllers.last
बुरक

@ बरक viewControllers.lastमें वर्तमान दृश्य नियंत्रक है, पिछले दृश्य नियंत्रक को प्राप्त करने के लिए एक का उपयोग करना चाहिएviewControllers[viewControllers.count-2]
गणपत

102

यहां स्वीकृत उत्तर का कार्यान्वयन है:

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

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

20
मैं इसे एक श्रेणी के रूप में जोड़ने की सलाह देता हूंUIViewController
MaxGabriel

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

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

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

यह सही "बैक व्यू कंट्रोलर" लौटाएगा, भले ही वर्तमान वर्ग नेविगेशन स्टैक पर न हो।


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

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

9

यहां प्रभु बीमन के स्विफ्ट कोड का एक संशोधित संस्करण है जो इसे स्विफ्ट 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
    }
}

नोटों की एक जोड़ी: रिवर्स () अब उलट है () और self.navigationController? .viewControllers में कभी भी "स्वयं" व्यू कंट्रोलर नहीं होता है, इसलिए स्टैक.लॉस्ट पर्याप्त होना चाहिए
Kappe

3

अभिभावक दृश्य नियंत्रक तक पहुंचने n-2के लिए viewControllersसंपत्ति के तत्व तक पहुंचें ।

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


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

3

UINavigationControllerविस्तार के रूप में :

extension UINavigationController {

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

}

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
    }

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

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

1

navigationControllerइसे पुनर्प्राप्त करने के लिए विधि का उपयोग करें । Apple की साइट पर प्रलेखन देखें ।

नेविगेशनकंट्रोलर एक अभिभावक या पूर्वज है जो एक नेविगेशन नियंत्रक है। (सिफ़ पढ़िये)

@property (गैर-परमाणु, आसानी से, बनाए रखना) UINavigationController * navigationController

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

उपलब्धता आईओएस 2.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];
}

1

एक अधिक रसीला स्विफ्ट आवेग:

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

0

पिछला दृश्य नियंत्रक सरल है।

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

एक के लिए, के बाद से एक रूट दृश्य नियंत्रक है, तो आप सिर्फ जगह ले सकता है lastObjectके साथ firstObjectप्राप्त करने के लिए।


0

स्विफ्ट 2.2 के लिए कार्यान्वयन - इसे UIViewControllerविस्तार में जोड़ें । इस दृष्टि से सुरक्षित है कि यह तब लौटेगा, 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
}

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

0

मेरा विस्तार, स्विफ्ट ३

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" को viewController द्वारा प्रतिस्थापित करना होगा जिसे आप वापस करना चाहते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.