2013-01-31 14 views
79

मेरे पास एक सैद्धांतिक प्रश्न है। अब मैं ऐप्पल की ViewController मार्गदर्शिका पढ़ रहा हूं।एक प्रस्तुत दृश्य नियंत्रक को खारिज कर रहा है

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

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

लेकिन मैं व्याख्या नहीं कर सकते, मैं क्यों में एक साधारण कॉल के बजाय प्रस्तुत कुलपति में एक प्रोटोकॉल बना सकते हैं और प्रतिनिधि varible जोड़ने के लिए, प्रस्तुत खारिज करते हुए कुलपति के लिए कुलपति पेश करने में प्रतिनिधि विधि बनाने के लिए, है प्रस्तुत दृश्य नियंत्रक विधि

[self dismissViewControllerAnimated:NO completion:nil]?

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

उत्तर

6

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

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

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

+0

लेकिन मैं की जरूरत है नहीं "अलग डेटा गुजर जब आदि अलग-अलग दृश्यों से खारिज करते हुए, विभिन्न तरीकों बुला जब खारिज, .." मैं प्रस्तुत दृश्य नियंत्रक विधि में एक छोटे से कॉल कर सकते हैं - - [स्वयं dismiss dismissViewControllerAnimated: कोई पूरा नहीं: शून्य]? – nikitahils

+0

हां, यही वह है जो मैं करूंगा। – jhilgert00

+0

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

87

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

[self dismissViewControllerAnimated:NO completion:nil] 

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

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

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

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

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

[स्विफ्ट]

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

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

+1

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

42

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

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

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

0

यदि आप मोडल उपयोग व्यू खारिज का उपयोग कर रहे हैं। देखें Controller Programming Guide से

[self dismissViewControllerAnimated:NO completion:nil]; 
+0

यह प्रश्न का उत्तर कैसे देता है: * "पहली पसंद बेहतर क्यों है? ऐप्पल इसकी सिफारिश क्यों करता है?" * – jww

2

बोली, "कैसे देखें नियंत्रकों वर्तमान अन्य दृश्य नियंत्रक"।

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

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

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

2

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

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

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

0

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

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

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

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

+0

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

33

स्विफ्ट 3

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

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

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

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

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

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

रूट दृश्य नियंत्रक पर वापस जाएं: (। ऑब्जेक्टिव-सी के लिए this answer के लिए धन्यवाद)

// 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]; 

documentation कहते हैं फोन करके खारिज कर सकते हैं,

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

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

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

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

  • This Objective-C answer इसमें थोड़ा सा जाता है।
  • Here एक स्विफ्ट उदाहरण है।
इस बिंदु मैं प्रतिनिधियों का उपयोग करने के बाद से मैं आम तौर पर एक नेविगेशन नियंत्रक या मोडल दृश्य नियंत्रकों है की जरूरत नहीं है, लेकिन अगर मैं भविष्य में the delegate pattern उपयोग करने की आवश्यकता है, मैं एक अद्यतन करने के लिए जोड़ देगा

5

इस प्रयास करें: तेज

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

स्विफ्ट 3.0 // को खारिज देखें नियंत्रक, मैं एक अन्य कारण के बारे में सोच सकते हैं क्यों यह हो सकता है एक अनिश्चित स्थिति से खुद को बचाने के लिए एक अच्छा तरीका बनें:

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

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

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

0

माइकल Enriquez के जवाब के अलावा में

[self dismissViewControllerAnimated:true completion:nil]; 
0

स्विफ्ट

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

     if (rootViewController.presentedViewController != nil) { 
      rootViewController.dismiss(animated: true, completion: { 
       //completion block. 
      }) 
     } 
संबंधित मुद्दे