प्रस्तुत दृश्य नियंत्रक को खारिज करना


116

मेरा एक सैद्धांतिक प्रश्न है। अब मैं Apple का ViewController गाइड पढ़ रहा हूं ।

उन्होंने लिखा:

जब प्रस्तुत दृश्य नियंत्रक को खारिज करने का समय आता है, तो पसंदीदा दृष्टिकोण प्रस्तुतकर्ता नियंत्रक को इसे खारिज करने देता है। दूसरे शब्दों में, जब भी संभव हो, दृश्य नियंत्रक प्रस्तुत करने वाला वही दृश्य नियंत्रक को इसे खारिज करने की जिम्मेदारी भी लेनी चाहिए। यद्यपि प्रस्तुत दृश्य नियंत्रक को सूचित करने के लिए कई तकनीकें हैं कि इसके प्रस्तुत दृश्य नियंत्रक को खारिज कर दिया जाना चाहिए, पसंदीदा तकनीक प्रतिनिधि है।

लेकिन मैं यह नहीं समझा सकता कि मुझे प्रस्तुत वीसी में एक प्रोटोकॉल क्यों बनाना है और डेलीगेट वेरिएबल को जोड़ना है, वीसी को प्रस्तुत करने के लिए वीसी को प्रस्तुत करने में प्रतिनिधि विधि बनाना है, प्रस्तुत व्यू कंट्रोलर विधि में एक साधारण कॉल के बजाय

[self dismissViewControllerAnimated:NO completion:nil]?

पहली पसंद बेहतर क्यों है? Apple इसकी सिफारिश क्यों करता है?

जवाबों:


122

मुझे लगता है कि ऐप्पल एपीआई के संभावित कुल्डी टुकड़े के लिए अपनी पीठ को थोड़ा सा यहां कवर कर रहे हैं।

  [self dismissViewControllerAnimated:NO completion:nil]

वास्तव में एक बेला है। यद्यपि आप कर सकते हैं - वैध रूप से - इसे प्रस्तुत दृश्य नियंत्रक पर कॉल करें, यह सब कुछ वर्तमान दृश्य नियंत्रक पर संदेश को अग्रेषित करता है। यदि आप कुलपति को बर्खास्त करने के ऊपर और ऊपर कुछ भी करना चाहते हैं, तो आपको यह जानने की आवश्यकता होगी, और आपको इसे एक प्रतिनिधि विधि के रूप में उसी तरह से व्यवहार करने की आवश्यकता है - जैसा कि यह बहुत ज्यादा है, एक बेक्ड-कुछ हद तक अनम्य में प्रतिनिधि विधि।

शायद वे लोगों द्वारा बुरे कोड के भार को समझ गए हैं कि वास्तव में यह समझ में नहीं आता है कि यह कैसे एक साथ रखा जाता है, इसलिए उनकी सावधानी।

लेकिन निश्चित रूप से, अगर आपको केवल इतना करना है कि बात को खारिज कर दिया जाए, तो आगे बढ़ें।

मेरा अपना दृष्टिकोण एक समझौता है, कम से कम यह मुझे याद दिलाता है कि क्या चल रहा है:

  [[self presentingViewController] dismissViewControllerAnimated:NO completion:nil]

[स्विफ्ट]

  self.presentingViewController?.dismiss(animated: false, completion:nil)

26
यह ध्यान दिया जाना चाहिए कि उपयोग presentingViewControllerकरना ज्यादातर बेकार है क्योंकि यह संदर्भित करेगा कि UINavigationControllerक्या selfएक में एम्बेडेड है। किस स्थिति में, आप बिलकुल नहीं मिल पाएंगे presentingViewController। फिर भी, [self dismissViewControllerAnimated:completion]अभी भी उस मामले में काम करता है। मेरा सुझाव यह है कि जब तक Apple इसे ठीक नहीं करता, तब तक इसका उपयोग जारी रहेगा।
memmons

4
मुझे यह पसंद है कि यह उत्तर अभी भी 3 साल बाद पूरी तरह से प्रासंगिक है।
user1021430

1
विचार करने के लिए कुछ और यह है कि एक दृश्य नियंत्रक यह नहीं जानता कि यह कैसे प्रदर्शित किया गया था। इसे प्रस्तुत किया जा सकता है, एक नेविगेशन नियंत्रक, एक टैब बार नियंत्रक आदि के हिस्से पर धकेल दिया गया है। प्रतिनिधि का उपयोग करके "नियंत्रक" दृश्य नियंत्रक को देखने के लिए जो भी विधि इसे प्रस्तुत करने के लिए उपयोग की गई थी, के व्युत्क्रम का उपयोग करते हुए "नियंत्रक" को अनुमति देता है।
डेविड स्मिथ

51

स्विफ्ट 3 के लिए अपडेट किया गया

मैं यहां केवल वर्तमान (प्रस्तुत) देखें नियंत्रक को खारिज करना चाहता था। मैं इसी उद्देश्य के साथ यहां आने वाले किसी भी व्यक्ति के लिए यह उत्तर दे रहा हूं।

नेविगेशन नियंत्रक

यदि आप एक नेविगेशन नियंत्रक का उपयोग कर रहे हैं, तो यह काफी आसान है।

पिछले दृश्य नियंत्रक पर वापस जाएं:

// Swift
self.navigationController?.popViewController(animated: true)

// Objective-C
[self.navigationController popViewControllerAnimated:YES];

मूल दृश्य नियंत्रक पर वापस जाएं:

// Swift
self.navigationController?.popToRootViewController(animated: true)

// Objective-C
[self.navigationController popToRootViewControllerAnimated:YES];

( इस उत्तर के लिए धन्यवाद उद्देश्य-सी के लिए ।)

मोडल व्यू कंट्रोलर

जब एक दृश्य नियंत्रक को मामूली रूप से प्रस्तुत किया जाता है, तो आप कॉल करके इसे (दूसरे दृश्य नियंत्रक से) खारिज कर सकते हैं

// Swift
self.dismiss(animated: true, completion: nil)

// Objective-C
[self dismissViewControllerAnimated:YES completion:nil];

प्रलेखन कहते हैं,

प्रस्तुत दृश्य नियंत्रक उस दृश्य नियंत्रक को खारिज करने के लिए जिम्मेदार है जिसे उसने प्रस्तुत किया है। यदि आप इस विधि को प्रस्तुत दृश्य नियंत्रक पर कहते हैं, तो UIKit प्रस्तुतकर्ता नियंत्रक को बर्खास्तगी को संभालने के लिए कहता है।

इसलिए यह प्रस्तुत दृश्य नियंत्रक के लिए इसे स्वयं कॉल करने के लिए काम करता है। यहाँ एक पूर्ण उदाहरण है।

प्रतिनिधियों

ओपी का सवाल प्रतिनिधियों के दृष्टिकोण को खारिज करने की जटिलता के बारे में था।

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


50

यह दृश्य नियंत्रक पुन: प्रयोज्य के लिए है।

अगर यह एक मोडल के रूप में प्रस्तुत किया जा रहा है, तो आपके दृश्य नियंत्रक को परवाह नहीं करनी चाहिए, एक नेविगेशन नियंत्रक या जो भी हो, पर धकेल दिया जाएगा। यदि आपका दृश्य नियंत्रक खुद को खारिज कर देता है, तो आप मान रहे हैं कि इसे मामूली रूप से प्रस्तुत किया जा रहा है। आप नेविगेशन कंट्रोलर पर उस व्यू कंट्रोलर को पुश नहीं कर पाएंगे।

एक प्रोटोकॉल को लागू करके, आप मूल दृश्य नियंत्रक को यह तय करने देते हैं कि इसे कैसे प्रस्तुत / धकेला और खारिज / पॉप किया जाना चाहिए।



6

मेरे अनुभव में, यह तब काम आता है जब आपको इसे किसी भी तरह से खारिज करने की आवश्यकता होती है ViewController से आप करने वाले प्रत्येक viewcontroller के लिए अलग-अलग कार्य करते हैं। कोई भी व्यूकंट्रोलर जो प्रोटोकॉल को अपनाता है वह दृश्य को अपने तरीके से खारिज कर सकता है। (आईपैड बनाम आईफोन, या अलग-अलग विचारों को खारिज करने पर अलग-अलग डेटा पास करना, खारिज करते समय विभिन्न तरीकों को कॉल करना, आदि)

संपादित करें:

इसलिए, स्पष्ट करने के लिए, यदि आप कभी भी यह करना चाहते हैं कि दृश्य को खारिज कर दिया जाए, तो मुझे प्रतिनिधि प्रोटोकॉल सेटअप करने की कोई आवश्यकता नहीं है। अगर आपको अलग- अलग प्रेजेंटिंग व्यू कंट्रोलर्स से इसे खारिज करने के बाद अलग-अलग चीजें करने की जरूरत है, तो डेलिगेट का इस्तेमाल करना आपका सबसे अच्छा तरीका होगा।


लेकिन अगर मुझे अलग-अलग विचारों से खारिज करते समय "अलग-अलग डेटा पास करने की आवश्यकता नहीं है, तो खारिज करते समय अलग-अलग तरीकों को कॉल करना, आदि।" क्या मैं प्रस्तुत व्यू कंट्रोलर विधि में एक छोटी कॉल कर सकता हूं - [स्वयं बर्खास्त मत करो।
निकिताहिल्स

प्रस्तुतकर्ता को प्रस्तुत दृश्य को खारिज करते हुए, यह स्पष्ट करता है कि प्रस्तुतकर्ता वास्तव में तैयार है और अग्रभूमि में वापसी को संभाल रहा है: निष्पादन अनुक्रम का पालन करना आसान है, और किसी भी यूआई अपडेट की जिम्मेदारी स्पष्ट रूप से स्पष्ट है।
जोहान

2

कंट्रोलर प्रोग्रामिंग गाइड के उद्धरण , "हाउ व्यू व्यू कंट्रोलर्स प्रेजेंट अदर व्यू कंट्रोलर्स"।

प्रस्तुत दृश्य नियंत्रकों की एक श्रृंखला में प्रत्येक दृश्य नियंत्रक श्रृंखला में इसके आसपास की अन्य वस्तुओं को इंगित करता है। दूसरे शब्दों में, एक प्रस्तुत दृश्य नियंत्रक जो किसी अन्य दृश्य नियंत्रक को प्रस्तुत करता है, उसके प्रेजेंटिंग व्यू कॉन्ट्रोलर और प्रेज व्यूवॉन्ट्रोलर दोनों में मान्य ऑब्जेक्ट हैं। आप इन संबंधों का उपयोग आवश्यकतानुसार देखने के लिए श्रंखला नियंत्रक के माध्यम से कर सकते हैं। उदाहरण के लिए, यदि उपयोगकर्ता वर्तमान ऑपरेशन को रद्द करता है, तो आप पहले प्रस्तुत दृश्य नियंत्रक को हटाकर श्रृंखला की सभी वस्तुओं को हटा सकते हैं। किसी व्यू कंट्रोलर को खारिज करना न केवल उस व्यू कंट्रोलर को बल्कि किसी भी व्यू कंट्रोलर को भी खारिज कर देता है।

तो एक तरफ यह एक अच्छा संतुलित डिजाइन, अच्छा डे-कपलिंग, आदि के लिए बनाता है ... लेकिन दूसरी ओर यह बहुत व्यावहारिक है, क्योंकि आप जल्दी से नेविगेशन में एक निश्चित बिंदु पर वापस आ सकते हैं।

हालाँकि, मैं व्यक्तिगत रूप से अनजाने सहकर्मियों का उपयोग करने की अपेक्षा पीछे की ओर प्रस्तुत करने वाले दृश्य नियंत्रक पेड़ को पार करने की कोशिश करूँगा , जो कि इस अध्याय में Apple के बारे में बात करता है जहाँ बोली है।


2

एक बिंदु यह है कि यह एक अच्छा कोडिंग दृष्टिकोण है। यह बहुतों को संतुष्ट करता हैOOP सिद्धांतों को है, जैसे।, एसआरपी, चिंताओं का पृथक्करण आदि।

तो, दृश्य को प्रस्तुत करने वाला दृश्य नियंत्रक इसे खारिज करने वाला होना चाहिए।

जैसे, एक रियल एस्टेट कंपनी जो किराए पर घर देती है, उसे वापस लेने का अधिकार होना चाहिए।


2

स्विफ्ट 3.0 // स्विफ्ट में नियंत्रक देखें को खारिज करें

self.navigationController?.popViewController(animated: true)
dismiss(animated: true, completion: nil)

1

माइकल एनरिकेज़ के जवाब के अलावा, मैं एक और कारण के बारे में सोच सकता हूं कि यह एक अनिर्धारित स्थिति से खुद को बचाने का एक अच्छा तरीका हो सकता है:

ViewControllerA देखें ViewControllerB को औपचारिक रूप से प्रस्तुत करता है। लेकिन, जब से आपने ViewControllerA के लिए कोड नहीं लिखा होगा, तो आप ViewControllerA के जीवनचक्र से अवगत नहीं होंगे। यह आपके व्यू कंट्रोलर, ViewControllerB को प्रस्तुत करने के बाद 5 सेकंड (कह) को खारिज कर सकता है।

इस मामले में, यदि आप बस का उपयोग कर रहे थे dismissViewController खुद को खारिज करने के लिए ViewControllerB एक अपरिभाषित स्थिति में समाप्त हो जाएंगे - शायद एक दुर्घटना या एक काली स्क्रीन नहीं बल्कि आपके दृष्टिकोण से एक अपरिभाषित राज्य।

यदि, इसके बजाय, आप प्रतिनिधि पैटर्न का उपयोग कर रहे थे, तो आप ViewControllerB की स्थिति से अवगत होंगे और आप मेरे द्वारा बताए गए मामले की तरह कार्यक्रम कर सकते हैं।


1

तीव्र

let rootViewController:UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!

        if (rootViewController.presentedViewController != nil) {
            rootViewController.dismiss(animated: true, completion: {
                //completion block.
            })
        }

0

यदि आप मोडल उपयोग दृश्य खारिज कर रहे हैं।

[self dismissViewControllerAnimated:NO completion:nil];

यह सवाल का जवाब कैसे देता है: "पहली पसंद बेहतर क्यों है? ऐप्पल इसकी सिफारिश क्यों करता है?"
3

0

यह बहुत बालोनी है। आवश्यकता होने पर प्रतिनिधिमंडल ठीक है लेकिन अगर यह कोड को अधिक जटिल बनाता है - और यह करता है - तो इसके लिए एक कारण होना चाहिए।

मुझे यकीन है कि Apple के पास इसके कारण हैं। लेकिन यह स्पष्ट और अधिक संक्षिप्त रूप से प्रस्तुत वीसी को खारिज करना है जब तक कि अन्यथा करने के लिए कोई सही कारण नहीं है और आज तक यहां किसी ने भी ऐसा नहीं किया है जिसे मैं देख सकता हूं।

प्रोटोकॉल उत्कृष्ट होते हैं जब उनकी आवश्यकता होती है लेकिन ऑब्जेक्ट ओरिएंटेड डिज़ाइन कभी भी एक दूसरे के साथ अनावश्यक रूप से संचार करने वाले मॉड्यूल के बारे में नहीं था।

टॉम लव (उद्देश्य सी के सह-डेवलपर) ने एक बार टिप्पणी की थी कि ऑब्जेक्टिव सी "सुरुचिपूर्ण", "छोटा", "कुरकुरा" और "अच्छी तरह से परिभाषित" (जब सी ++ के साथ तुलना की गई थी)। उसके लिए कहना आसान है। प्रत्यायोजन एक उपयोगी विशेषता है जो ऐसा लगता है कि "सिर्फ इसलिए" का उपयोग किया गया है, और जब मैं भाषा में काम करना पसंद करता हूं, तो मैं चीजों को और अधिक जटिल बनाने के लिए अनावश्यक वाक्यविन्यास का उपयोग करने के लिए मजबूर करने के विचार को फैला देता हूं।


यह आपको शुरू में कुछ कोड बचा सकता है, लेकिन आपका दृष्टिकोण आपके कोड आधार के बढ़ने के कारण आपको कई सिर दर्द देगा। आपको ऑब्जेक्ट ओरिएंटेड सिद्धांतों को समझना चाहिए जैसे कि चिंताओं को अलग करना, अन्यथा आप अपने पूरे एप्लिकेशन को एक बड़ी फ़ाइल में कोड कर सकते हैं।
वर्नर Altewischer

-2

आप अपनी सुपर व्यू विंडो को बंद कर सकते हैं

self.view.superview?.window?.close()

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