स्टोरीबोर्ड - AppDelegate में ViewController का संदर्भ लें


122

इस परिदृश्य पर विचार करें: मेरे पास एक स्टोरीबोर्ड-आधारित ऐप है। मैं स्टोरीबोर्ड में एक ViewController ऑब्जेक्ट जोड़ता हूं, इस ViewController के लिए प्रोजेक्ट में क्लास फाइलें जोड़ता हूं और IB पहचान निरीक्षक में नए वर्ग का नाम निर्दिष्ट करता हूं। अब मैं इस ViewController को AppDelegate से प्रोग्रामेटिक रूप से कैसे संदर्भित करने जा रहा हूं? मैंने संबंधित वर्ग के साथ एक चर बनाया है और इसे एक IBOutlet संपत्ति में बदल दिया है, लेकिन मुझे कोड में नए ViewController को संदर्भित करने में सक्षम होने का कोई तरीका नहीं दिखता है - किसी कनेक्शन को ctrl-drag करने का कोई भी प्रयास काम नहीं करता है ।

यानी AppDelegate के भीतर मैं इस तरह बेस ViewController को प्राप्त कर सकता हूं

(MyViewController*) self.window.rootViewController

लेकिन स्टोरीबोर्ड के भीतर किसी भी अन्य ViewController के बारे में कैसे?


इस उत्तर की जाँच करें । यह तेज है, लेकिन भाषाएं समान हैं।
बोरझ

जवाबों:


165

पर एक नज़र डालें प्रलेखन के लिए -[UIStoryboard instantiateViewControllerWithIdentifier:]। यह आपको IB अट्रिब्यूट्स इंस्पेक्टर में पहचाने जाने वाले पहचानकर्ता का उपयोग करके अपने स्टोरीबोर्ड से एक दृश्य नियंत्रक को तुरंत हटाने की अनुमति देता है:

यहाँ छवि विवरण दर्ज करें

उदाहरण कोड जोड़ने का कार्य:

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard"
                                                         bundle: nil];

MyViewController *controller = (MyViewController*)[mainStoryboard 
                    instantiateViewControllerWithIdentifier: @"<Controller ID>"];

हाय रॉबिन, उस के लिए धन्यवाद! मैंने इस दस्तावेज़ को देखा, लेकिन शब्द तुरंत और आरंभिक मिलाया गया ... यह हमें वहां मिलता है (आपके निर्देश के बाद :) (जवाबों में कोड स्वरूपण की कमी लानत है ...) UIStoryboard * mainStoryboard = [UIStoryboard स्टोरीबोर्डWithName: @ "मेनस्टोरीबोर्ड" बंडल: नील]; MyViewController * thisController = (MyViewController *) [mainStoryboard InstantiateViewControllerWithIdentifier: @ "myvc"];
माथियास डी

मैंने आपके उदाहरण कोड को किसी ऐसे व्यक्ति के लिए प्रारूपण के साथ उत्तर में जोड़ दिया है जो इस पर देख रहा है।
रॉबिन समरहिल

24
यदि आप एक सार्वभौमिक ऐप बना रहे हैं तो MainStoryboard_iPhone / MainStoryboard_iPad का उपयोग करना सुनिश्चित करें अन्यथा आपको दुर्घटना हो जाएगी।
roocell

16
प्रतिनिधि के भीतर से आप अपनी जानकारी द्वारा लोड स्टोरीबोर्ड उदाहरण तक पहुँच सकते हैं। इस तरह से: [[[self window] rootViewController] storyboard] डॉक्स के अनुसार यह "स्टोरीबोर्ड जिससे व्यू कंट्रोलर की उत्पत्ति हुई है।" (या शून्य अगर यह एक स्टोरीबोर्ड से नहीं आया)। उस UIStoryboard * से आप @RobinSummerhill वर्णित तात्कालिक कॉल का उपयोग कर सकते हैं। ध्यान दें कि स्टोरीबोर्ड आपके व्यू-कॉन्ट्रॉलर्स ( दृश्यों ) के नए उदाहरणों को त्वरित करता है, क्योंकि वे आवश्यक हैं और उन लोगों को फिर से उपयोग नहीं करते हैं जो पहले देखे गए थे।
तद बुमरोट

6
मेरा मानना ​​है कि ओपी पूरी तरह से रनिंग वीसी पर कैसे जाना चाहता है। कैसे एक लोड करने के लिए नहीं। ठीक ही जैसा कि वह बताते हैं, आप इस स्व.विंडो .rootViewController को कहने में सक्षम थे और अब आप और नहीं कर सकते।
फेटी

41

यदि आप XCode5 का उपयोग करते हैं तो आपको इसे अलग तरीके से करना चाहिए।

  • अपने चयन UIViewControllerमेंUIStoryboard
  • Identity Inspectorदाएँ शीर्ष फलक पर जाएँ
  • Use Storyboard IDचेकबॉक्स की जाँच करें
  • Storyboard IDक्षेत्र के लिए एक अद्वितीय आईडी लिखें

फिर अपना कोड लिखें।

// Override point for customization after application launch.

if (<your implementation>) {
    UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" 
                                                             bundle: nil];
    YourViewController *yourController = (YourViewController *)[mainStoryboard 
      instantiateViewControllerWithIdentifier:@"YourViewControllerID"];
    self.window.rootViewController = yourController;
}

return YES;

4
जहाँ तक मुझे पता है और इसे आज़माने में सक्षम था, यह अद्यतन उत्तर है।
gnclmorais

एक्सटेंशन के बिना एक स्टोरीबोर्ड का नाम इसका नाम है, इसलिए यह "Main_iPhone" या "Main_iPad" भी हो सकता है यदि आपने अपना प्रोजेक्ट इस तरह सेट किया है।
ब्रायन व्हाइट

और फिर हम लॉगिन के बाद मूल rootViewController पर वापस कैसे संक्रमण करते हैं। कम से कम iOS 7 और Xcode 5.0.2 के बारे में मेरी जानकारी - रूट व्यू कंट्रोलर को वापस बदलना तत्काल और एनीमेशन के बिना व्यू पदानुक्रम को बदल देगा। UX टीम ने कम के लिए कोडर्स की हत्या की है।
lol

मैं स्विफ्ट का उपयोग कैसे करूंगा?
लियो डबस

8

आम तौर पर, सिस्टम को स्टोरीबोर्ड के साथ व्यू कंट्रोलर इंस्टेंटेशन को हैंडल करना चाहिए। आप जो चाहते हैं वह self.window.rootViewControllerव्यू कंट्रोलर पदानुक्रम का पता लगाने के लिए है, जैसा कि आप अपने स्टोरीबोर्ड को ठीक से सेटअप करने पर पहले से ही सही ढंग से आरंभीकृत किया जाना चाहिए, जो व्यू कंट्रोलर्स को शुरू करने के लिए एक संदर्भ को हथियाने के द्वारा है।

तो, rootViewControllerमान लें कि आपका UINavigationController है और फिर आप इसके शीर्ष दृश्य नियंत्रक को कुछ भेजना चाहते हैं, आप इसे अपने AppDelegate में इस तरह से करेंगे didFinishLaunchingWithOptions:

UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
MyViewController *myVC = (MyViewController *)nav.topViewController;
myVC.data = self.data;

स्विफ्ट में अगर बहुत समान होगा:

let nav = self.window.rootViewController as! UINavigationController;
let myVC = nav.topViewController as! MyViewController
myVc.data = self.data

जब तक आप सामान्य तरीके से स्टोरीबोर्ड लोड नहीं किया जाता है और पूरे स्टोरीबोर्ड को स्वयं लोड करना चाहते हैं, तब तक आपको ऐप प्रतिनिधि से स्टोरीबोर्ड आईडी का उपयोग करके दृश्य नियंत्रकों को प्रारंभिक रूप से निर्धारित नहीं करना चाहिए। यदि आप AppDelegate से दृश्यों को इनिशियलाइज़ करने वाले हैं, तो आप संभवतः कुछ गलत कर रहे हैं। मेरा मतलब है कि आप किसी कारण से, स्टैक के नीचे व्यू कंट्रोलर तरीके से डेटा भेजना चाहते हैं, AppDelegate को डेटा सेट करने के लिए व्यू कंट्रोलर स्टैक में रास्ता नहीं बनाना चाहिए। वह इसका व्यवसाय नहीं है। यह व्यवसाय rootViewController है। RootViewController को अपने बच्चों को संभालने दें! इसलिए, यदि मैं सिस्टम द्वारा सामान्य स्टोरीबोर्ड लोड करने की प्रक्रिया को बायपास कर रहा था, तो इसके लिए संदर्भ को हटाकर info.plist फ़ाइल में, मैं rootViewController का उपयोग करते हुए सबसे अधिक त्वरित रूप से करना चाहूंगाinstantiateViewControllerWithIdentifier:, और संभवतः इसकी जड़ अगर यह एक कंटेनर है, जैसे कि UINavigationController। जो आप बचना चाहते हैं, वह दृश्य नियंत्रकों को त्वरित करने के लिए है जो स्टोरीबोर्ड द्वारा पहले से ही इंस्टेंट किए गए हैं। यह एक समस्या है जिसे मैं बहुत कुछ देखता हूं। संक्षेप में, मैं स्वीकृत उत्तर से असहमत हूं। यह गलत है जब तक कि पोस्टर का मतलब स्टोरीबोर्ड को जानकारी से लोड करना नहीं है। तब से जब तक आप 2 स्टोरीबोर्ड लोड नहीं करेंगे, अन्यथा इसका कोई मतलब नहीं है। यह शायद एक मेमोरी लीक नहीं है क्योंकि सिस्टम ने रूट दृश्य को इनिशियलाइज़ किया और इसे विंडो को सौंपा, लेकिन फिर आप साथ आए और इसे फिर से शुरू किया और इसे फिर से असाइन किया। आपका ऐप बहुत खराब शुरुआत के लिए बंद है!


0
    UIStoryboard * storyboard = [UIStoryboard storyboardWithName:@"Tutorial" bundle:nil];
    self.window.rootViewController = [storyboard instantiateInitialViewController];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.