2013-05-28 11 views
7

हर कोई जानता है कि आप UIViewController init/viewDidLoad विधि पर फ्रेम आकार पर भरोसा नहीं कर सकते हैं; इस:UIViewController viewDidLoad गलत चौड़ाई/ऊंचाई

- (void)viewDidLoad: { 
    NSLog(@"%d", self.view.frame.size.width); 
} 

कई अवसरों में गलत आकार प्रिंट होगा (विशेष रूप से यह बहुत ज्यादा लैंडस्केप मोड में टूट गया है)

यह होगा वास्तव में हमेशा सही किया परिणाम वापस तो यह subviews लेआउट अच्छा है:

- (void)viewWillAppear: { 
    NSLog(@"%d", self.view.frame.size.width); 
} 

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

तो सवाल एक है: क्या सबव्यूज़ पोजिशनिंग को संभालने का कोई बेहतर तरीका है?

प्रश्न दो बहुत संबंधित हैं, मान लें कि मेरे पास विभिन्न अन्य सबव्यू सहित यूआईवीव का सबक्लास है। मैं इसे अपने इंटरफ़ेस के अंदर घोषित करता हूं, और मैं इसे अपने init/viewDidLoad विधि में आवंटित/इनिट करता हूं।

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    ... 
    menu = [[SNKSlidingMenu alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
    ... 
} 

हम पहले से ही जानते हैं अब हम viewWillAppear में इसका स्थान बदलना एक और अधिक सटीक पढ़ने

- (void)viewWillAppear:(BOOL)animated{ 
    .... 
    menu.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
    .... 
} 

समस्या यह है कि पाठ्यक्रम के सभी subviews रूप में अच्छी तरह पुनर्निर्धारित किए जाने की जरूरत है पाने के लिए की जरूरत है। यह लेआउटसब्यूव्स फ़ंक्शन द्वारा किया जाता है जिसे स्वचालित रूप से कॉल किया जाता है, लेकिन हमें एक ही समस्या मिलती है: सभी सबव्यूज़ को SNKSlidingMenu क्लास के इंटरफ़ेस के अंदर घोषित करने की आवश्यकता है .. क्या इसके आसपास कोई तरीका है?

धन्यवाद।

+1

ऑटोलायआउट का उपयोग करें, या ऑटोरेसाइजिंग मास्क सेट करें? – jrturton

उत्तर

7

आपके पास iOS 5.0 लक्ष्यीकरण कर रहे हैं या बेहतर आप परिवर्तन करना viewWillLayoutSubviews और viewDidLayoutSubviews उपयोग कर सकते हैं।

आपके दूसरे प्रश्न के लिए, यदि आपको init की तुलना में अन्य विधि में इंस्टेंस वैरिएबल तक पहुंच की आवश्यकता है, तो आपको इसे रखने की आवश्यकता है, मुझे इसके साथ कोई समस्या नहीं दिखाई दे रही है।

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

+0

सहमत हुए, लेकिन फिर यह प्रत्येक बेवकूफ को प्रारंभ करने के लिए initWithFrame का उपयोग करने के लिए बहुत बेवकूफ है। मुझे बहुत सारे डुप्लिकेट कोड की तरह लगता है, और ऐसा लगता है कि आपको बहुत सारे आवृत्ति चर का उपयोग करने में मजबूर करता है। ऑटो लेआउट केवल नए आईओएस के लिए हैं। – ksn

+0

पुराने 'ऑटोरेसाइजिंग मास्क' आपके लिए भी पर्याप्त हो सकता है। डुप्लिकेट कोड के लिए: यदि आप उस कोड को बहुत अधिक डुप्लिकेट कर रहे हैं, तो आप कस्टम 'UIView' उप-वर्ग बना सकते हैं ताकि आप डुप्लिकेट न करें, या आपके लिए विचार बनाने वाले सहायक तरीके हों। यदि आप अधिक कोड पोस्ट करते हैं तो हम आपकी मदद करने में सक्षम हो सकते हैं। – pgb

6

viewDidLoad केवल बुलाया हो जाता है जब आपके विचार बनाया है, लेकिन चीजों के बहुत सारे frame के आकार को प्रभावित कर सकते हैं, और इसे फिर से जब frame परिवर्तन कहा जाता प्राप्त करता है।

बजाय:

  • viewDidLoad
  • में subviews बनाने viewWillLayoutSubviews में उनके आकार निर्धारित किया है।

रोटेशन से निपटने के लिए यहां कुछ अतिरिक्त चर्चा देखें: https://stackoverflow.com/a/16421170/1445366

2

viewWillLayoutSubviews और viewDidLayoutSubviews इस समस्या को हल कर सकते हैं।
लेकिन दो मेटेड अधिक बार प्रदर्शन किए जाएंगे। यह सही है self.view.frame पाने के लिए यह मेरा कोड है।

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    ... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
    // init you view and set it`s frame. this can get correct frame. 
    ... 
    } 
    ... 
} 
+0

यह एकमात्र समाधान है जो मेरे लिए काम करता है। हालांकि, यह Swift4 के लिए कुछ अजीब प्रारंभिक दृश्य दूसरा एक विभाजन खुलेगी, जैसा कि में dispatch_async किक से पहले थोड़े बदसूरत है :। \t \t DispatchQueue.main.async { \t \t} –