2009-02-13 27 views
17

क्या वस्तु UIViewController रोटेशन विधि कॉल dipatching के लिए जिम्मेदार है, यानी:UIViewController बारी बारी से तरीकों

  • shouldAutorotateToInterfaceOrientation:
  • willRotateToInterfaceOrientation:duration:
  • willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:
  • willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:
  • didRotateFromInterfaceOrientation:

मुझे लगता है कि यह UIApplication है (लेकिन शायद ऐपडिलेगेट या UIWindow)।

अगला प्रश्न यह है कि ऑब्जेक्ट कैसे पता चलता है कि UIViewController से बात करने के लिए?

यह कैसे पता चलता है कि UIViewController में इसका दृश्य खिड़की के सबव्यूव के रूप में है?

क्या कोई संदेश है जिसे आप भेज सकते हैं या एक संपत्ति जिसे आप सेट कर सकते हैं (कुछ ऑब्जेक्ट) जो ऐप के लिए "सक्रिय" UIViewController सेट करता है?

+0

अच्छा सवाल, मुझे दिनों से मेरे दिमाग में यह संदेह था। इसी तरह के सवाल पूछने वाला था और इस पर टक्कर लगी! –

+0

मुझे अपने प्रश्न पूछना चाहिए जैसा आपने किया था। ये सार्वभौमिक से संबंधित सभी प्रश्न हैं, "कस्टम ढांचा, दस्तावेज़ीकरण पढ़ें, ठीक है अब मुझे कैसे पता होना चाहिए कि यह सब कैसे काम करना चाहिए"। –

उत्तर

13

ऐसा लगता है कि UIApplication सक्रिय दृश्य नियंत्रक को संदेश भेज रहा है।

लेकिन आपके व्यू कंट्रोलर इंस्टेंस को इन संदेशों को कैसे प्राप्त होता है?

संदेश को पहले दृश्य नियंत्रक को अग्रेषित किया गया है जिसका दृश्य UIWindow उदाहरण में जोड़ा गया है।

  1. ViewController जिसका दृश्य है UIWindow उदाहरण में सीधे जोड़े (एकल दृश्य एप्लिकेशन)

  2. एक नेविगेशन में नेविगेशन नियंत्रक आधारित:

    यह 3 बुनियादी परिदृश्यों करने पर निर्भर करता ऐप, नेविगेशन नियंत्रक सक्रिय दृश्यों के लिए संदेश आगे नियंत्रक देखें।

  3. एक टैब बार आधारित अनुप्रयोग में टैब बार नियंत्रक, तो टैब बार नियंत्रक सक्रिय दृश्यों नियंत्रक देखने (या सक्रिय नेविगेशन नियंत्रक) के लिए संदेश अग्रेषित करता है।

आपके पास समस्या होगी, यदि आप एकाधिक दृश्यों वाला ऐप बनाते हैं, लेकिन नेविगेशन नियंत्रक या टैब बार नियंत्रक का उपयोग न करें। यदि आप मैन्युअल रूप से UIWindow इंस्टेंस के अंदर और बाहर विचारों को स्वैप करते हैं, तो आपको इन संदेशों को विश्वसनीय रूप से प्राप्त नहीं होगा। यह इस तरह से पोस्ट के समान है: iPhone viewWillAppear not firing

बस ऐसे कई दृश्य के लिए एप्पल के सम्मेलनों का उपयोग करें और आप ठीक हो। उम्मीद है कि यह कुछ एक घंटे या दो

+0

हालांकि एक संदेह है, क्या नेविगेशन नियंत्रक/टैब बार नियंत्रक संदेश को सबव्यू के नियंत्रकों को पास करता है या फिर वे केवल विचारों का आकार बदलते हैं? मुझे लगता है कि वे केवल अपने सबव्यूज़ का आकार बदलते हैं, पहला व्यू कंट्रोलर संदेश को अपने पदानुक्रम के नीचे नहीं भेजता है, वे केवल अपने सबव्यूज़ का आकार बदलते हैं। –

+0

बिल्कुल, ऐप्पल प्रति स्क्रीन केवल एक वीसी का उपयोग करने की सिफारिश करता है। तो "उप" दृश्य नियंत्रकों का उपयोग करना समर्थित नहीं है और संदेशों को स्वचालित रूप से अग्रेषित नहीं किया जाता है। –

+0

कोरी, प्रति स्क्रीन एक वीसी पर खुद को सीमित करना कैसे संभव है, उदाहरण के लिए आपके पास एक ऐप है जिसके लिए एक ही स्क्रीन पर दो टेबल दृश्यों की आवश्यकता है? आपको प्रत्येक तालिका दृश्य के लिए वीसी की आवश्यकता होगी, फिर दोनों को प्रबंधित करने के लिए एक वीसी। या एक और उदाहरण पर विचार करें: एक ऐप जिसे टैब-बार की तरह व्यवहार की आवश्यकता होती है लेकिन ग्राफिकल/कला आवश्यकताओं के लिए कस्टम टैब बार नियंत्रक की आवश्यकता होती है? प्रति स्क्रीन केवल एक वीसी होने के कारण जटिल यूआई के लिए एक अक्षम लक्ष्य लगता है। इन मामलों में, इंटरफेस रोटेशन घटनाओं को विश्वसनीय रूप से नियंत्रित करने के लिए * कुछ * तरीका होना चाहिए? – Yetanotherjosh

4

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

(लेकिन यदि आप डीबगर के साथ घूमते हैं, तो आप मेरे पास एक ही निष्कर्ष पर आ सकते हैं: प्रत्येक नियंत्रक के दृश्य को नियंत्रक को वापस मैप करने के कुछ प्रकार की आंतरिक तालिका है, और संदेश उस लिंक के आधार पर प्रेषित किए जाते हैं।)


अद्यतन: यह जब मैं पहली बार इस जवाब लिखा 2009 में सही मायने में निजी जादू था, लेकिन आईओएस के लिए बाद में परिवर्तन सार्वजनिक इसके पीछे एपीआई बना दिया है। रूट व्यू कंट्रोलर अब UIWindow.rootViewController संपत्ति के माध्यम से सुलभ है, और UIViewController.childViewControllers संपत्ति का उपयोग करके वंशज दृश्य नियंत्रकों का पेड़ बनाया गया है।

अभिभावक दृश्य नियंत्रक अपने बच्चों के अभिविन्यास परिवर्तनों को सूचित करने के लिए ज़िम्मेदार हैं। (मुझे यकीन नहीं है कि रूट व्यू कंट्रोलर को कैसे अधिसूचित किया जाता है, लेकिन आप ब्रेकपॉइंट सेट कर सकते हैं और खुद को ढूंढ सकते हैं।) -shouldAutomaticallyForwardRotationMethods विधि यह तय करती है कि UIViewController आपके लिए यह करेगा या नहीं। यदि यह NO देता है, तो आप अपने -willRotateToInterfaceOrientation:duration:, -willAnimateRotationToInterfaceOrientation:duration:, और -didRotateFromInterfaceOrientation: विधियों में ऐसा करने के लिए ज़िम्मेदार बन जाते हैं।

+0

यह वास्तव में जादू है, +1। रूट व्यू कंट्रोलर घुमाया जाता है और आकार बदलता है और उप-दृश्यों के फ्रेम बदलते हैं और ऑटोरेसाइजिंग मास्क के आधार पर आकार बदलते हैं। पता नहीं क्यों लोगों ने इस गरीब आदमी को वोट दिया है! –

+0

+1, मुझे इस उत्तर को वोट करने का कोई कारण नहीं दिख रहा है। यह एक शर्म की बात है कि लोग यह नहीं कहते कि वे एक जवाब क्यों देते हैं। –

+0

ऊपर उल्लिखित कारणों के लिए मतदान किया गया। –

4

यह कैसे पता चलेगा कि UIViewController के दृश्य के रूप में कौन सा दृश्य है?

UIViewController क्लास दृश्यों और उनके दृश्य नियंत्रकों के बीच एक स्थिर मानचित्र बनाए रखता है। कोको टच के अंदर कुछ प्रमुख स्थानों में यह मानचित्र पूछताछ की गई है। विशेष रूप से, [UIView nextResponder] इसे पूछताछ करता है और यदि पाया जाता है तो नियंत्रक लौटाता है।

मुझे लगता है कि UIWindow रूट रूट के साथ एक ही लुकअप करता है यह जानने के लिए कि कौन सा नियंत्रक रोटेशन ईवेंट को आगे बढ़ाने के लिए करता है। अगली बार यह जांच लेंगे कि मैं अलग-अलग हिस्सों में कुछ देख रहा हूं। (मैंने समझने के लिए कुछ समय रिवर्स-इंजीनियरिंग कोकोटा टच बिताया है कि चीजें कैसे काम करती हैं।)

1

मुझे एक ही समस्या है।

मेरे पास लैंडस्केप ओरिएंटेशन (बाएं और दाएं परिदृश्य दोनों) में काम करने वाला एक गेम है।

एक बहु-दृश्य अनुप्रयोग को प्रबंधित करने के लिए मैं एक रूट UIviewController का उपयोग करता हूं, यानी एक डमी UIViewcontroller एक UIview के साथ जो कुछ भी नहीं करता है। इसके बाद मैं सबव्यूव के रूप में इसे अन्य सभी यूआईवीव्यू जोड़ता हूं।

ऐप शुरू करते समय, एमुलेटर जल्दी से पोर्ट्रेट अभिविन्यास पर घूमता है, और मुझे अपने फ्रेम में से प्रत्येक दृश्य (0, -80,320,480) जैसा लगता है। इसके परिणामस्वरूप दाईं तरफ 160 x 320 आयत से देखा जा रहा है।

मैंने देखा है कि - चाहिएऑटोरोटेट टॉइंटरफेसऑरिएंटेशन: प्रत्येक सबव्यू का तरीका केवल एक बार बुलाया जाता है, और यह तब होता है जब इसे रूट व्यू में जोड़ा जाता है। बाद में, डिवाइस को घूर्णन करते समय, केवल रूट व्यू को इसकी विधि कहा जाता है।

अनजाने में, किसी भी - विलुप्त * विधियों की कॉल केवल रूट व्यू पर भेजी जाती है, इसलिए, उपविभागों में से किसी भी विधि को परिभाषित करना व्यर्थ है।

इन विधियों को हर बार कहा जाता है कि अभिविन्यास को अभिविन्यास में बदल दिया गया है - चाहिएऑटोरोटेट टॉइंटरफेसऑरिएंटेशन: विधि। इसलिए मैंने सोचा कि मैं वहां से अपने सबव्यूज़ की फ्रेम संपत्ति को छोटा कर सकता हूं।

इसे पूरा करने के मैं अपने rootViewController कक्षा में निम्न विधि परिभाषित:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration 
{ 
    subview1_ViewController.view.frame = CGRectMake(0,0,480,320); 
    subview2_ViewController.view.frame = CGRectMake(0,0,480,320); 
     ... 
} 

मुझे समझ नहीं आता क्यों फ्रेम संपत्ति अपडेट नहीं किया गया है, लेकिन मैं इस समाधान का काम करता है।

उम्मीद है कि यह मदद करता है ....

संबंधित मुद्दे

 संबंधित मुद्दे