मुझे एक धक्का नियंत्रक से रूटव्यूकंट्रोलर कैसे मिलेगा?


137

इसलिए, मैं RootViewController से एक दृश्य नियंत्रक को धक्का देता हूं जैसे:

[self.navigationController pushViewController: एक और ViewController एनिमेटेड: हाँ];

लेकिन, anotherViewControllerअब, मैं फिर से RootViewController का उपयोग करना चाहते हैं।

मैं कोशिश कर रहा हूँ

// (अब एक और ViewController के अंदर)
/// RootViewController * root = (RootViewController *) self.parentViewController; // नहीं।
// गलत
RootViewController * root = (RootViewController *) [self.navigationController.viewControllers objectAtIndex: 0]; // हाँ!! यह काम करता हैं

मुझे यकीन नहीं है कि यह काम क्यों कर रहा है और मुझे यकीन नहीं है कि अगर यह करने का सबसे अच्छा तरीका है। क्या किसी ने रूटव्यूकंट्रोलर को किसी कंट्रोलर से प्राप्त करने के लिए उस रूटव्यूकंट्रोलर के नेविगेशनकंट्रोलर में धकेल दिया है या नहीं और जिस तरह से मैंने इसे किया है या नहीं, क्या यह विश्वसनीय है या नहीं, इस पर कोई बेहतर तरीके से टिप्पणी कर सकता है।


आपने जो किया है वह मूल रूप से रूट व्यू कंट्रोलर (नेविगेशन पदानुक्रम में पहला) होगा, यदि आप "बैक" व्यू कंट्रोलर तक पहुंच प्राप्त करना चाहते हैं, तो मेरा उत्तर देखें।
बेन एस

जवाबों:


133

का प्रयोग करें viewControllers UINavigationController की संपत्ति। उदाहरण कोड:

// Inside another ViewController
NSArray *viewControllers = self.navigationController.viewControllers;
UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];

यह "बैक" व्यू कंट्रोलर प्राप्त करने का मानक तरीका है। कारण objectAtIndex:0काम करता है क्योंकि आप जिस एक्सेस कंट्रोलर तक पहुंचने का प्रयास कर रहे हैं, वह भी रूट एक है, यदि आप नेविगेशन में गहरे थे, तो बैक व्यू रूट के व्यू के समान नहीं होगा।


6
:) ty। यह अभी भी हैकी लग रहा है - :) मैं वास्तव में एक "आधिकारिक" सदस्य को नौकरी करने के लिए चाहता था, self.navigationController.rootViewController की तरह कुछ, लेकिन अफसोस, ऐसी कोई बात नहीं ..
बॉबोबोबो

62
उपरोक्त कोड गलत है। इससे पहले rootViewControllerगायब *है, और सूचकांक बस होना चाहिए 0। प्रश्न में कोड सही है:RootViewController *root = (RootViewController *)[navigationController.viewControllers objectAtIndex:0]
ma11hew28

2
सहमत: उपरोक्त कोड मूल दृश्य नियंत्रक लौटाता है , न कि ओपी के अनुसार रूट व्यू कंट्रोलर। फिर भी, बेन एस ने कहा कि वह क्या करेगा, उसने बस इतना नहीं बताया।
इवान वुज़िका

दूसरी पंक्ति को पढ़ना चाहिए: UIViewController * rootViewController = [viewControllers objectAtIndex: viewControllers.count - 1];
बिली

177

स्विफ्ट संस्करण:

var rootViewController = self.navigationController?.viewControllers.first

उद्देश्य संस्करण:

UIViewController *rootViewController = [self.navigationController.viewControllers firstObject];

जहां स्व एक UIVAVController का एक उदाहरण है जो एक UINavigationController में एम्बेडेड है।


क्या मुझे एक अलग वर्ग से दूसरे ViewController का नेवीगेशन कंट्रोलर मिल सकता है?
sasquatch

किसी भी UIViewController उपवर्ग में एक नेविगेशनकंट्रोलर गुण होगा, जो इंगित करता है कि यह पहली पेरेंटव्यूकंट्रोलर है जो UINavigationController क्लास से मेल खाता है।
dulgan

12

एक ही बात का थोड़ा कम बदसूरत संस्करण इन सभी उत्तरों में बहुत अधिक उल्लेख किया गया है:

UIViewController *rootViewController = [[self.navigationController viewControllers] firstObject];

आपके मामले में, मैं शायद कुछ ऐसा करूंगा:

अपने UINavigationController उपवर्ग के अंदर :

- (UIViewController *)rootViewController
{
    return [[self viewControllers] firstObject];
}

तो आप उपयोग कर सकते हैं:

UIViewController *rootViewController = [self.navigationController rootViewController];

संपादित करें

ओपी ने टिप्पणियों में संपत्ति मांगी।

यदि आप चाहें, तो आप इसे कुछ इस तरह से एक्सेस कर सकते हैं जैसे self.navigationController.rootViewControllerकि आपके हेडर में केवल एक प्रॉपर्टी को जोड़कर:

@property (nonatomic, readonly, weak) UIViewController *rootViewController;

8

उन सभी के लिए जो एक तेजी से विस्तार में रुचि रखते हैं, यह वही है जो मैं अभी उपयोग कर रहा हूं:

extension UINavigationController {
    var rootViewController : UIViewController? {
        return self.viewControllers.first
    }
}

1
धन्यवाद! इसके अलावा आप "के रूप में? UIViewController" हटा सकते हैं
atereshkov

3

करने के लिए एक अतिरिक्त के रूप @ dulgan के जवाब है, यह हमेशा उपयोग करने के लिए एक अच्छा तरीका है firstObjectसे अधिक objectAtIndex:0है, क्योंकि, जबकि पहले एक रिटर्न शून्य अगर वहाँ सरणी में कोई वस्तु है, बाद एक अपवाद फेंकता है।

UIViewController *rootViewController = self.navigationController.rootViewController;

वैकल्पिक रूप से, आपके लिए नाम की श्रेणी बनाना एक बड़ा प्लस होगा UINavigationController+Additions और उस में अपनी पद्धति को परिभाषित ।

@interface UINavigationController (Additions)

- (UIViewController *)rootViewController;

@end

@implementation UINavigationController (Additions)

- (UIViewController *)rootViewController
{
    return self.viewControllers.firstObject;
}

@end

मैंने सिर्फ आपके उत्तर को पढ़े बिना इस भाग को जोड़ दिया, आप "FirstObject" के साथ पूरी तरह से सही हैं, बेहतर थान [0]
dulgan

1

कैसे के बारे में UIApplication सिंगलटन अपने keyWindow के लिए पूछ रहा है , और उस से UIWindow रूट व्यू कंट्रोलर (इसकी rootViewController संपत्ति) के लिए पूछें :

UIViewController root = [[[UIApplication sharedApplication] keyWindow] rootViewController];

नेविगेशन नियंत्रक कैसे प्राप्त करें?
येस्ते मुराटोव

यह एक गलत सुझाव है कि क्या होगा यदि मेरे आवेदन का रूटव्यू कंट्रोलर UITabBarViewController है?
संदीप सिंह राणा

1

यहां मैं किसी भी स्थान से रूट पर जाने के लिए सार्वभौमिक विधि के साथ आया था।

  1. आप इस वर्ग के साथ एक नई क्लास फ़ाइल बनाते हैं, ताकि यह आपके प्रोजेक्ट में कहीं से भी सुलभ हो:

    import UIKit
    
    class SharedControllers
    {
        static func navigateToRoot(viewController: UIViewController)
        {
            var nc = viewController.navigationController
    
            // If this is a normal view with NavigationController, then we just pop to root.
            if nc != nil
            {
                nc?.popToRootViewControllerAnimated(true)
                return
            }
    
            // Most likely we are in Modal view, so we will need to search for a view with NavigationController.
            let vc = viewController.presentingViewController
    
            if nc == nil
            {
                nc = viewController.presentingViewController?.navigationController
            }
    
            if nc == nil
            {
                nc = viewController.parentViewController?.navigationController
            }
    
            if vc is UINavigationController && nc == nil
            {
                nc = vc as? UINavigationController
            }
    
            if nc != nil
            {
                viewController.dismissViewControllerAnimated(false, completion:
                    {
                        nc?.popToRootViewControllerAnimated(true)
                })
            }
        }
    }
  2. आपके प्रोजेक्ट में कहीं से भी उपयोग:

    {
        ...
        SharedControllers.navigateToRoot(self)
        ...
    }

0

यह मेरे लिए काम किया:

जब मेरा रूट व्यू कंट्रोलर नेविगेशन कंट्रोलर में लगा हो:

UINavigationController * navigationController = (UINavigationController *)[[[[UIApplication sharedApplication] windows] firstObject] rootViewController];
RootViewController * rootVC = (RootViewController *)[[navigationController viewControllers] firstObject];

याद रखें कि keyWindowपदावनत किया जाता है।

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