2012-09-21 14 views
55

मैं आईओएस 6 ऑटो लेआउटआईओएस ऑटोलाउट - फ्रेम आकार चौड़ाई प्राप्त करें

का उपयोग कर विकास कर रहा हूं, मैं दृश्य की फ्रेम चौड़ाई प्रदर्शित करने वाला एक संदेश लॉग करना चाहता हूं।

मैं स्क्रीन पर टेक्स्ट व्यू देख सकता हूं।

लेकिन मुझे चौड़ाई और ऊंचाई शून्य के रूप में मिलती है, क्या मुझे कुछ याद आ रही है?

NSLog(@"textView = %p", self.textView); 
NSLog(@"height  = %f", self.textView.frame.size.height); 
NSLog(@"width  = %f", self.textView.frame.size.width); 

textView = 0x882de00 
height  = 0.000000 
width  = 0.000000 

उत्तर

56

मुझे लगता है कि ऑटो लेआउट में आपके द्वारा इसे कॉल किए जाने तक आपके विचारों को लेआउट करने का समय नहीं था। viewDidLoad के समय ऑटो लेआउट नहीं हुआ है, क्योंकि इसे दृश्य लोड होने के ठीक बाद कहा जाता है और इसके बाद ही दृश्य दृश्य नियंत्रक के दृश्य पदानुक्रम में रखे जाते हैं और अंत में (दृश्य के layoutSubviews विधि में) रखा जाता है।

संपादित करें: यह उत्तर बताता है कि प्रश्न में परिदृश्य क्यों काम नहीं करता है। @dreamzor's answer बताता है कि इसे हल करने के लिए अपने कोड को कहां रखा जाए।

+0

मैंने 'viewDidLoad' में संदेश लॉग करने का प्रयास किया। ऑटो लेआउट पूरा होने के बाद कौन सी विधि लागू की जाती है। कारण मैं पूछता हूं क्योंकि उपयोगकर्ता टेक्स्टव्यू के साथ बातचीत कर सकने से पहले चौड़ाई की गणना करना चाहता हूं। तो ऑब्जेक्ट विवरण लॉगिंग करने से bcuz की मदद नहीं हो सकती है, मैं कुछ अन्य गणना के लिए चौड़ाई का उपयोग करना चाहता हूं। – user1046037

+1

नहीं, ऑटो व्यू से पहले 'viewDidLoad' होता है।एक दृश्य को किसी अन्य दृश्य में जोड़ने के बाद ऑटो लेआउट आलसी हो जाता है (जो 'व्यूविल्लएपियर' के तुरंत बाद होता है, लेकिन शायद 'viewDidAppear' से पहले विश्वसनीय नहीं है)। जानने का एकमात्र विश्वसनीय तरीका यह जानना है कि दृश्य नियंत्रक के दृश्य पर 'layoutSubviews' कब समाप्त होता है। – Jesper

+1

फिर भी आप फ्रेम को पाने का प्रयास क्यों कर रहे हैं? यदि आप इसके आधार पर गणना करना चाहते हैं और स्वयं लेआउट करना चाहते हैं, तो आप शायद ऑटो लेआउट से जूझ रहे हैं। – Jesper

28

समाधान

  • प्लेस autolayout पूर्ण होने से पहले में viewDidAppear

कारण

  • viewDidLoad कि कोड होता है। इसलिए स्थिति अभी तक ऑटोलायआउट द्वारा सेट नहीं की गई है जो xib
  • viewDidAppear ऑटोलायआउट पूरा होने के बाद होता है।
+1

मैंने कोड को DidAppear में रखा और फिर भी, मेरे दृश्य का फ्रेम NSLog शून्य दिखाता है। – dreamzor

+0

असल में देखेंDidAppear को आईओएस 6.0 के लिए viewDidLayoutSubviews से पहले बुलाया जाता है, इसलिए dreamzor सही है। – vedrano

+4

आईओएस 6 में, मेरे परीक्षण के आधार पर, मैंने दूसरे नियंत्रक में नेविगेशन नियंत्रक का उपयोग किया, 'viewDidLayoutSubviews' को 'viewDidAppear' से पहले बुलाया गया था, लेकिन' viewDidLayoutSubviews 'में सबव्यू की फ्रेम चौड़ाई शून्य बनी हुई है। केवल 'viewDidAppear' में, सबव्यू की फ्रेम चौड़ाई सही मान प्रतीत होती है। – user1046037

147

असल में, उत्तर के ऊपर बिल्कुल सही नहीं हैं। मैंने उनका पीछा किया और बार-बार शून्य हो गया।

चाल viewDidLayoutSubviews विधि करने के लिए अपने फ्रेम निर्भर कोड है, जो

सूचना देता है कि अपने दृश्य सिर्फ अपनी subviews बाहर रखी दृश्य नियंत्रक जगह है।

यह मत भूलना कि इस विधि को कई बार कहा जाता है और यह व्यू कंट्रोलर के जीवन चक्र का हिस्सा नहीं है, इसलिए इसका उपयोग करते समय सावधान रहें।

आशा है कि यह किसी के लिए सहायक होगा।

बस जोड़ना चाहता था, कि मेरे प्रोग्राम के लिए लैंडस्केप मोड के बिना ऑटो लेआउट का उपयोग नहीं करना बहुत आसान है ...मैंने कोशिश की है, हालांकि = डी

+9

अनुभव से, ऑटोलायआउट के काम के बाद यह सबसे पुराना कॉलबैक है। मैं उदाहरण के लिए, उदाहरण के लिए, पहली बार पकड़ने के लिए एक बूल कहलाता हूं और फ्रेम निर्भर तर्क करता हूं। यह बहुत ही सुरुचिपूर्ण नहीं है लेकिन विशिष्ट ऑटोलायआउट बाधाओं के लिए उचित कॉलबैक होने तक काम पूरा हो जाता है। – ArkReversed

+3

@dreamzor, मुझे कैसे पता चलेगा कि यह अंतिम दृश्य है DidLayoutSubviews? मैंने आईओएस 7 पर पाया, केवल एक दृश्यDidLayoutSubviews को ViewDidAppear से पहले बुलाया जाएगा, लेकिन आईओएस 8 पर, मैं viewDidAaypear देखने से पहले एकाधिक दृश्य DidLayoutSubviews देखता हूं। यह कष्टप्रद है, क्योंकि पहली बारDidLayoutSubviews आईओएस 8 पर गलत फ्रेम आकार देगा, इसलिए मुझे इसे पहली बार अनदेखा करना होगा – Wingzero

+0

@ विंगजेरो मेरी परियोजना में पांचवां समय सही है, तो मैं दूसरों को कैसे नजरअंदाज कर सकता हूं? –

13

असल में मैं बल लेआउट अद्यतन करने में कामयाब मेरी कोड viewDidLoad भीतर से पहले:

override func viewDidLoad() { 
     super.viewDidLoad() 

     println("bounds before \(self.previewContainer.bounds)"); 
     //on iPhone 6 plus -> prints bounds before (0.0,0.0,320.0,320.0) 

     self.view.setNeedsLayout() 
     self.view.layoutIfNeeded() 

     println("bounds after \(self.previewContainer.bounds)"); 
     //on iPhone 6 plus -> prints bounds after (0.0,0.0,414.0,414.0) 

     //Size dependent code works here 
     self.create() 
    } 

अद्यतन: यह अब और काम करने के लिए

25

प्रतीत नहीं होता अपने दृश्य में शामिल करेंडलोड()

self.view.setNeedsLayout() 
self.view.layoutIfNeeded() 

yourv तक पहुंचने से पहले iew.frame.size.width

2

आईओएस autolayout - फ्रेम आकार चौड़ाई मिल

ऊपर जवाब में से
-(void) layoutSubviews{ 
     [self layoutIfNeeded]; 
     //right you code to set frame its will work to get frame and set frame. 
     CALayer *bottomBorder = [CALayer layer]; 
     bottomBorder.frame = CGRectMake(0.0f, bkView.frame.size.height - 1, bkView.frame.size.width, 1.0f); 
     bottomBorder.backgroundColor = [UIColor blackColor].CGColor; 
     [bkView.layer addSublayer:bottomBorder]; 
    } 
5

कोई भी मेरे लिए पूरी तरह से काम किया, viewDidLoad को छोड़कर, लेकिन वह नहीं प्रदर्शित करने के पक्ष प्रभाव पड़ता है जो दृश्य मैं एनिमेटेड होने के बाद तक चाहता हूं, जो खराब दिखता है।

viewDidLayoutSubviews कोड कि autolayout पूरा किया जा रहा है पर निर्भर करता है चलाने के लिए सही जगह होना चाहिए, लेकिन के रूप में अन्य लोगों ने बताया है कि हाल के iOS संस्करण में कई बार कहा जाता है और आपको पता नहीं कर सकते हैं जो अंतिम कॉल है।

तो मैंने इसे एक छोटे से हैक के साथ हल किया। मेरी स्टोरीबोर्ड में, mySubview इसके self.view से छोटा होना चाहिए। लेकिन जब viewDidLayoutSubviews पहली बार कहा जाता है, mySubview अभी भी 600 की चौड़ाई है, जबकि self.view सही ढंग से सेट किया गया प्रतीत होता है (यह एक आईफोन प्रोजेक्ट है)। तो मुझे बस इतना करना है कि बाद की कॉल मॉनीटर करें और सापेक्ष चौड़ाई की जांच करें। एक बार mySubviewself.view से छोटा है, तो मुझे यकीन है कि इसे सही तरीके से निर्धारित किया गया है।

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    if self.mySubview.bounds.size.width < self.view.bounds.size.width { 

     // mySubview's width became less than the view's width, so it is 
     // safe to assume it is now laid out correctly... 

    } 
} 

यह हार्ड-कोडेड संख्या पर निर्भर नहीं का लाभ दिया है, तो यह सभी iPhone फार्म कारकों पर काम कर सकते हैं, उदाहरण के लिए। बेशक यह सभी मामलों में या सभी उपकरणों पर एक पैनसिया नहीं हो सकता है, लेकिन सापेक्ष आकारों के समान चेक करने के लिए शायद कई सरल तरीके हैं।

और नहीं, हमें ऐसा करने की ज़रूरत नहीं है, लेकिन जब तक ऐप्पल हमें कुछ और विश्वसनीय कॉलबैक नहीं देता है, हम सब इसके साथ फंस गए हैं।

7

यह वास्तव में अजीब विशेषता है। लेकिन मैंने पाया:

आप layoutsubviews विधि का उपयोग कर के बिना फ्रेम प्राप्त करना चाहते हैं, यह एक का उपयोग करें:

dispatch_async(dispatch_get_main_queue(), ^{ 
     NSLog(@"View frame: %@", NSStringFromCGRect(view.frame)); 
    }); 

यह वास्तव में अजीब है !!!

+0

आपको बहुत बहुत धन्यवाद – Subramani

0

आप केवल पहले लेआउट पास के बाद आकार का पता लगा सकते हैं। या फिर आपको नीचे की वास्तविक चौड़ाई मिलने के बाद विधि के नीचे कॉल करें।

[yourView layoutIfNeeded]; 
संबंधित मुद्दे