2012-07-17 27 views
34

की सही सीमाएं प्राप्त करना मेरे पास एक आईपैड-एप्लिकेशन है। परिदृश्य अभिविन्यास में UIViewController की वास्तविक वास्तविक चौड़ाई = 1024px और ऊंचाई = 768 - 20 (स्टेटसबार) - 44 (नेविगेशनबार) = 704pxUIViewController के दृश्य

तो मैं यह [1024 x 704] आकार प्राप्त करना चाहता हूं और मैं इसके लिए self.view.bounds का उपयोग कर रहा हूं। यह [748 x 1024] देता है, जो गलत है! लेकिन जब मैं स्क्रीन को दो बार घुमाता हूं (वर्तमान -> चित्र -> वर्तमान), दृश्य की सीमाएं सही हैं - [1024 x 704]

दृश्य इस तरह प्रारंभ किया गया था:

- (void)loadView { 
    self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
    self.view.backgroundColor = [UIColor lightGrayColor]; 
} 

और सीमा इस तरह मिल थे:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSLog(@"bounds = %@", NSStringFromCGRect(self.view.bounds)); 
} 
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
    NSLog(@"bounds = %@", NSStringFromCGRect(self.view.bounds)); 
} 

तो सवाल यह है .. मैं कैसे बहुत शुरुआत में सही दृश्य के लिए बाध्य प्राप्त कर सकते हैं ?

उत्तर

29

कुछ अन्य उत्तरों के मुताबिक, जो समस्या आप देख रहे हैं वह viewDidLoad से पहले घूर्णन होता है। चूंकि आईपैड हमेशा पोर्ट्रेट मोड में शुरू होता है, यदि आपको viewDidLoad में आकार मान मिलते हैं, तो वे हमेशा पोर्ट्रेट आकार होंगे - यह आपके द्वारा कॉन्फ़िगर किए गए किसी भी उन्मुखता के बावजूद है।

आकार के बाद प्राप्त करने के लिए अभिविन्यास/रोटेशन होता है, viewDidAppear में आकार मान प्राप्त करें।


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

+1

यदि आप भारी विचार बना रहे हैं, तो देखने में देरी हो सकती है उपस्थिति, आप 'viewWillAppear' –

+0

का उपयोग करके देरी को कम कर सकते हैं मैंने दृश्यविल्लियर की कोशिश की। यह वांछित के रूप में काम नहीं करता है। ऐसा लगता है कि दृश्य दिखाई देने के बाद सीमा गणना की जाती है। – Billy

+1

मैं दृढ़ता से ** viewDidAppear का उपयोग करने की सलाह नहीं देता 'आपका दृश्य स्क्रीन पर है और इस बिंदु से उपयोगकर्ता को दिखाई देता है और आपके द्वारा किए गए परिवर्तन अचानक और दृश्यमान ग्लिच का कारण बन सकते हैं। यह रोटेशन (आदि) के दौरान दृश्य आकार में परिवर्तनों का जवाब देने में आपकी सहायता नहीं करेगा। [इसके बजाय, उपयोग करें 'viewWillLayoutSubviews'] (http://stackoverflow.com/a/42275589/2547229) (प्रकटीकरण: मेरे उत्तर के लिंक) जिस तरह से आईओएस इसे संभालने का तरीका है। – Benjohn

2

यह वही है मैं अपने पिछले परियोजना में पाया जाता है: self.view के फ्रेम के अनुसार viewDidLoad के बाद समायोजित किया जाएगा इस स्क्रीन नेविगेशन पट्टी आदि

तो हो सकता है आप (viewDidLoad के बाद कि मूल्य का उपयोग करना चाहते है तो शायद दृश्य में देखें या देखेंडिडएपियर) या बार की ऊंचाई को घटाकर इसे मैन्युअल रूप से समायोजित करें।

+0

मैं इसे पहले से ही 'viewDidLoad' विधि' में उपयोग कर रहा हूं और उसके बाद। और जब तक मैं स्क्रीन घुमाता हूं तब सीमाएं गलत रहती हैं। मैन्युअल घटाव खराब समाधान है, क्योंकि एप्लिकेशन सभी उपकरणों और उन्मुखताओं के लिए लक्षित है .. – demon9733

+3

क्या आप इसे देखने के बाद इसका उपयोग करेंगे? मेरे मामले में, viewDidAppear सही आकार लौटाएगा। – Selkie

13

मैं हमेशा उपयोग किया है:

CGSize sizeOfScreen = [[UIScreen mainScreen] bounds].size; 

स्क्रीन के आकार पाने के लिए, और:

CGSize sizeOfView = self.view.bounds.size; 

view के आकार पाने के लिए। मैं सिर्फ viewDidLoad पर यह परीक्षण किया है और यह दिखाई:

2012-07-17 10:25:46.562 Project[3904:15203] bounds = {768, 1004} 

कौन सा सही है के बाद से CGSize {चौड़ाई, ऊंचाई} के रूप में परिभाषित किया गया है।

+1

हां, यह घूर्णन के बाद ही काम करता है :( – demon9733

+0

यह अजीब बात है। तथ्य यह है कि आप आकार को आकार में प्राप्त कर रहे हैं, इससे कोई फर्क नहीं पड़ता क्योंकि दृश्य "पहले ही लोड हो चुका है" – Luke

2

मैं इस मुद्दे में भाग गया और पाया कि viewDidAppear में सीमाएं प्राप्त करने से मेरी ज़रूरतों के लिए काम किया गया।

12

इस सही ढंग से

आपका UIViewController उपवर्ग विधि viewWillLayoutSubviews, see also here ओवरराइड करना चाहिए कैसे करना है।

जब इस विधि को कॉल किया जाता है, तो व्यू कंट्रोलर का view का सही आकार होता है और आप सबव्यूज़ पर लेआउट पास से पहले सबव्यू में आवश्यक समायोजन कर सकते हैं।

प्रलेखन

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

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

कई गलत इस

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

  • viewDidLoad और viewWillAppear - इन कॉल view दौरान अभी तक अपनी अंतिम आकार में नहीं है। आपके द्वारा प्राप्त आकार को केवल शुद्ध मौका द्वारा सही किया जाएगा, ताकि आपको गुमराह किया जा सके। कृपया, मैं आपसे विनती करता हूं, इन विधियों का उपयोग न करें।
  • viewDidAppear - यह बहुत देर हो चुकी है। आपका विचार पहले से ही स्क्रीन पर है और उपयोगकर्ता को पर दिखाई देता है। यहां परिवर्तन करने से दृश्य परिवर्तन/अचानक ग्लिच हो जाएंगे और भयानक शौकिया घंटे बकवास की तरह दिखेगा। एक बार फिर, कृपया - मेरे लिए, मेरे लिए, के लिए सभी के खातिर: ऐसा मत करो! आप इससे बेहतर हैं और आपके उपयोगकर्ता भी हैं।
  • UIScreen.mainScreen.bounds.size - यह है अत्यधिक निम्न स्तर। आप UIViewController को कार्यान्वित कर रहे हैं और इसके दृश्य का आकार नियंत्रकों पर निर्भर करता है (नेविगेशन, टैब, पेजिंग, कोई कस्टम कंट्रोलर इत्यादि), डिवाइस कैसे घुमाया जाता है, और संभावित रूप से, स्क्रीन को कैसे विभाजित किया गया है मल्टीटास्किंग के लिए। इसलिए, जब आप इन सभी के लिए क्षतिपूर्ति करने में सक्षम हो सकते हैं और अपने दृश्य के अंतिम आकार की गणना कर सकते हैं, तो आप जटिल और भंगुर कोड के साथ समाप्त हो जाएंगे। UIViewController यह सब आपके लिए करता है यदि आप बस viewWillLayoutSubviews ओवरराइड करते हैं!

अन्य सही जानकारी प्रदान नहीं की तुलना में, इन टूट दृष्टिकोण ऑटो रोटेशन या अन्य घटनाओं का कारण दृश्य नियंत्रक का दृष्टिकोण इस तरह के मल्टीटास्किंग इशारों के रूप में आकार बदलने के लिए आप के साथ मदद नहीं करेगा। यह ऐसा कुछ है जिसे आप वास्तव में आसानी से संभालना चाहते हैं।

तो कृपया: एक चैंप बनें। यह सही तरीका है। viewWillLayoutSubviews का उपयोग करें। आपके कार्यान्वयन को प्रत्येक आकार में परिवर्तन के लिए बुलाया जाएगा, और आपके उपयोगकर्ता, भविष्य के स्वयं, टीम के सदस्य और मैं इसके लिए आपको मनाऊंगा। वाहवाही!

इसके अलावा सुझावों

जबviewWillLayoutSubviews कहा जाता है, अपने पदानुक्रम में केवल देखने कि अपनी अंतिम आकार में बदल दिया जाएगा viewController.view है। इसके लिए दे दो विधि के नाम पर है। यह आपको बता रही है view… (अपना दृश्य नियंत्रक के view) …WillLayout… (वास्तव में जल्द ही अब है, लेकिन यह अभी तक हुआ नहीं है) …Subviews (रूट दृश्य के तहत अपने पदानुक्रम में सब कुछ)।

तो सबव्यू लेआउट अभी तक नहीं हुआ है! प्रत्येक रूट के तहत बच्चे नहीं है अभी तक वैध अंतिम आकार है। बच्चे के विचारों से आप जो भी आकार की जानकारी पूछते हैं वह सर्वोत्तम पर पूरी तरह से गलत होगा।

बल्कि अधिक होने की संभावना, और असीम बदतर, यह गुमराह सही हो जाएगा!

यह होता है जो आप उम्मीद करते हैं और इस आकार और अभिविन्यास पर डिफ़ॉल्ट रूप से या आपकी स्टोरीबोर्ड सेटिंग्स के कारण डिफ़ॉल्ट होने की आवश्यकता होती है। लेकिन यह केवल मौके से है और ऐसा कुछ नहीं है जिसे आप अलग-अलग डिवाइस आकारों या उन्मुखताओं पर भरोसा कर सकते हैं।

आप की जरूरत है जब एक विशेष subview आकार बदलता है, और इसका सटीक अंतिम आकार पता बताया जाए, तो आप आम तौर पर उस विशेष UIView उपवर्ग के layoutSubviews विधि ओवरराइड करना चाहिए।

+0

उत्तर के लिए धन्यवाद! स्पष्टीकरण के लिए, क्या आप यह कह रहे हैं कि क्या हम कक्षा 'UIView' के सबव्यूव के आकार को जानना चाहते हैं, तो ठीक से ऐसा करने का एकमात्र तरीका है' लेआउटस्यूव्यूव्यू 'विधि (जिसे कस्टम क्लास बनाने की आवश्यकता होगी) को ओवरराइड करना है? – Crashalot

+0

@ क्रैशलोट ओवरराइडिंग एक उप-वर्ग के लिए समझ में आता है जो अपने बच्चों को बताता है। हालांकि, यदि आप अक्सर मौजूदा व्यू क्लास को ओवरराइड करने के बजाए इस व्यवहार को लिखना चाहते हैं तो यह समस्याग्रस्त हो सकता है। मैंने जो दृष्टिकोण लिया है वह एक विशिष्ट 'UIView' उपclass,' BoundsSenderView' बनाने के लिए है, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ _ _ यह कुछ भी प्रदर्शित नहीं करता है या स्पर्श का जवाब नहीं देता है।इसके बाद आप ऑटो लेआउट का उपयोग इस दृश्य पर पिन करने के लिए कर सकते हैं कि आप आकार चाहते हैं, और जब आप इस आकार के आकार में कॉलबैक प्राप्त करेंगे। – Benjohn

+0

लेआउट के बाद सबव्यूव के आकार को पाने के अन्य तरीके हो सकते हैं, लेकिन मुझे उनके बारे में पता नहीं है। आपको पूरा होने वाले पूर्ण लेआउट पास में शामिल होना होगा। – Benjohn