IOS 5 में कंट्रोलर कंटेंट कैसे काम करता है?


108

WWDC 2011 सत्र 102 में, एप्पल शुरू की दृश्य नियंत्रक नियंत्रण है, जो कस्टम दृश्य नियंत्रक कंटेनर बनाने की क्षमता, के अनुरूप है UITabBarController, UINavigationControllerऔर पसंद है।

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

परिदृश्य 1: बिना माता-पिता से नए माता-पिता के दृश्य नियंत्रक के आगे बढ़ना

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

क्या पहले दो पंक्तियों को दिए गए क्रम में होना चाहिए, या क्या वे उलट हो सकते हैं?

परिदृश्य 2: किसी पैरेंट व्यू कंट्रोलर से नो पेरेंट व्यू कंट्रोलर में जाना

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

क्या कॉल करना भी आवश्यक है [vc didMoveToParentViewController:nil]? सत्र 102 में उदाहरणों ने इस परिदृश्य में ऐसा नहीं किया , लेकिन मुझे नहीं पता कि यह एक चूक थी या नहीं।

परिदृश्य 3: एक पैरेंट व्यू कंट्रोलर से दूसरे में ले जाना

यह संभवतः निम्नलिखित तरीके से घटित होगा, क्योंकि प्रत्येक अभिभावक दृश्य नियंत्रक में तर्क को समझाया जाएगा।

// In the old parent
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];

// In the new parent
[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];

प्रशन

मेरा मुख्य प्रश्न यह है: क्या यह है कि नियंत्रक नियंत्रक को सामान्य रूप से कैसे काम करना चाहिए? क्या मैकेनिक्स ऊपर दिए गए सही हैं?

क्या कॉल करने willMoveToParentViewControllerसे पहले कॉल करना आवश्यक है addChildViewController? यह मेरे लिए तार्किक आदेश जैसा लगता है, लेकिन क्या यह कड़ाई से आवश्यक है?

क्या कॉल करने के didMoveToParentViewController:nilबाद कॉल करना आवश्यक है removeFromParentViewController?

जवाबों:


72

UIViewControllerडॉक्स जब और जब कॉल करने के लिए नहीं पर बहुत स्पष्ट हैं willMove/ didMoveतरीकों। की जाँच करें "एक कंटेनर देखें नियंत्रक को लागू करने" प्रलेखन।

डॉक्स कहते हैं, कि यदि आप ओवरराइड नहीं करते हैं addChildViewController, तो आपको कॉल willMoveToParentViewController:करने की विधि नहीं है । हालाँकि didMoveToParentViewController:, संक्रमण पूर्ण होने के बाद आपको विधि को कॉल करने की आवश्यकता है। "इसी तरह, यह willMoveToParentViewController:विधि को कॉल करने से पहले विधि को देखने के लिए कंटेनर व्यू कंट्रोलर की जिम्मेदारी है removeFromParentViewControllerremoveFromParentViewControllerविधि didMoveToParentViewController:चाइल्ड व्यू कंट्रोलर की विधि को कॉल करती है ।"

इसके अलावा, यहाँ एक उदाहरण दिया गया है और यहाँ नमूना कोड है

शुभ लाभ


17
मैं देख रहा हूं, इसलिए addChildViewControllerसंतुलित होना चाहिए didMoveToParentViewControllerऔर willMoveToParentViewControllerइसके साथ संतुलित होना चाहिए removeFromParentViewController। यही वह है जिसकी तलाश में मैं हूं। निश्चित नहीं कि मैंने इसे डॉक्स में कैसे याद किया।
ग्रेगरी हिगले

क्यों नहीं? आपको विल कॉल करने के लिए क्यों नहीं करना होगा ।MoveToParentViewController लेकिन कॉल करने के लिए haeMoToParentViewController?
user4951

क्योंकि डॉक्स का यही कहना है। Apple स्पष्ट रूप से लगता है कि हमें जानने की आवश्यकता नहीं है।

7
एनिमेशन के कारण इसका कारण है: कहते हैं कि आप अपना स्वयं का नेविगेशन नियंत्रक बना रहे हैं। स्लाइड-इन एनीमेशन की शुरुआत में, 'विलमोव' को कॉल करने की आवश्यकता होती है, और एनीमेशन के अंत में, 'डीडोव' को कॉल करने की आवश्यकता होती है। अब जब आप एनीमेशन की शुरुआत में 'addChild' कहते हैं, तो यह स्वचालित रूप से आपके लिए 'willMove' कहता है। लेकिन यह पता नहीं चल सकता है कि एनीमेशन कब (अगर वहाँ एक है) खत्म हो गया है, इसलिए आपको एनीमेशन के अंत में (या तुरंत कोई एनीमेशन नहीं) मैन्युअल रूप से 'doMove' को कॉल करना होगा।
क्रिस

2
और 'स्लाइड आउट' एनीमेशन के लिए, उदाहरण के लिए, बच्चे को हटाया जा रहा है, आपको एनीमेशन की शुरुआत में मैन्युअल रूप से 'विल' को कॉल करना होगा, क्योंकि uikit अन्यथा पता नहीं चलेगा कि कब आपके बच्चे के वीसी के 'व्यूविलाडिसपियर' को कॉल करें। और एनीमेशन के अंत में, जब आप removeFromParentViewController कहते हैं, तो यह आपके लिए 'didMove' को स्वचालित रूप से कॉल कर सकता है।
क्रिस

23

यह हिस्सा सही नहीं है:

[vc willMoveToParentViewController:self];
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

डॉक्स के अनुसार:

जब आपका कस्टम कंटेनर addChildViewController: विधि को कॉल करता है, तो यह स्वचालित रूप से willMoveToParentViewController: दृश्य नियंत्रक की विधि को एक बच्चे के रूप में जोड़ने से पहले कहता है।

इसलिए आपको [vc willMoveToParentViewController:self]कॉल की आवश्यकता नहीं है । जब आप कॉल करते हैं तो यह स्वचालित रूप से किया जाता है [self addChildViewController:vc]। यहाँ कोड नमूना फिर से है:

[self addChildViewController:vc];
// [vc willMoveToParentViewController:self] called automatically
[self.view addSubview:vc.view]; // or something like this.
[vc didMoveToParentViewController:self];

व्यू कंट्रोलर हटाने के लिए:

RemoveFromParentViewController विधि स्वचालित रूप से didMoveToParentViewController को कॉल करती है: बच्चे को हटाने के बाद चाइल्ड व्यू कंट्रोलर की विधि।

संभवत: यह कॉल है [oldVC didMoveToParentViewController:nil]

[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
// [vc didMoveToParentViewController:nil] called automatically

ऐसा प्रतीत होता है कि यदि अन्यथा किया जाता है, भले ही यह काम करने के लिए लगता है, प्रस्तुत ViewController पर प्रस्तुत किया गया है।
एड्रियन

डॉक्स कहते हैं कि didMoveToParentViewController " ऐड-चिल्ड व्यू कॉन्ट्रॉलर: मेथड" को कॉल करने के तुरंत बाद, यह तब निर्दिष्ट नहीं करता है जब आप वास्तव में बच्चे को सबव्यू जोड़ते हैं। मुझे आश्चर्य है कि अगर सभी को यह गलत मिला है। क्या कुछ Apple डॉक्स में एक उदाहरण है जिसके खिलाफ हम जांच कर सकते हैं?
रॉबर्ट

ध्यान दें: यदि आप जिस वस्तु को ले जा रहे हैं, उससे पहले आपको कॉल करने की आवश्यकता है, तो ओवरराइड वाली एक कस्टम क्लास है (जब तक कि आपका ओवरराइड इसे आंतरिक रूप से कॉल नहीं करता है)willMoveToParentViewControlleraddChildViewControlleraddChildViewController
बंकरड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.