2012-10-26 15 views
37

से पहले फ्रेम को सही ढंग से सेट करने में असमर्थ मैं सोच रहा था कि अगर कोई viewDidLoad और viewWillAppear में उप-दृश्य का फ्रेम सेट करता है तो परिवर्तन स्क्रीन पर प्रभाव नहीं लेते हैं, लेकिन यदि आप इसे viewDidAppear में सेट करते हैं तो वे करते हैं?viewDidAppear

मेरे मामले में मैं दो tableviews तो viewDidLoad में उन्हें नीचे शिफ्ट करने के लिए एक और दृश्य जो viewDidLoad में जोड़ा जाता है के लिए जगह के लिए के रूप में यह नहीं हमेशा यह प्रदर्शित करने के लिए आवश्यक है प्रयास कर के साथ एक कस्टम xib लोड हो रहा हूँ।

समस्या यह है कि जब मैं viewDidLoad या viewWillAppear में फ्रेम सेट करता हूं तो यह ऑब्जेक्ट पर सेट होता है, मैं इसे प्रिंट करके देख सकता हूं, लेकिन यह स्क्रीन पर दिखाई नहीं देता है। viewDidAppear पर मेरे सेट फ्रेम कॉल को स्थानांतरित करने से सब कुछ अपेक्षित काम करेगा।

क्या यह सोचना गलत है कि मुझे viewDidLoad में फ्रेम सेट करने में सक्षम होना चाहिए? जब कक्षा लेकिन कोई UI तत्व initialised किया गया है उन्हें संदर्भित करने के लिए किसी भी प्रयास को लोड किया जाता है और इसलिए ओवरराइट किया जाएगा या initialisation प्रक्रिया है जिसके viewDidLoad और viewDidAppear कॉल के बीच होता दौरान unavaliable

- (id)init { 
    if (self = [super initWithNibName:@"MyView" bundle:nil]) {} 

    return self; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.descriptionWebView = [[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)] autorelease]; 

    [self.view addSubview:self.descriptionWebView]; 

    self.tableView1.autoresizingMask = UIViewAutoresizingNone; 
    self.tableView2.autoresizingMask = UIViewAutoresizingNone; 

    [self.descriptionWebView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"...." withExtension:@"html"]]]; 

    table1LocationWithHeader = CGRectMake(self.tableView1.frame.origin.x, 200, self.tableView1.frame.size.width, self.tableView1.frame.size.height - 200); 
    table2LocationWithHeader = CGRectMake(self.tableView2.frame.origin.x, 200, self.tableView2.frame.size.width, self.tableView2.frame.size.height - 200); 

    //this will NOT work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    //this will NOT work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 


- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 

    //this WILL work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 


//I added these after comments for stack overflow users, it seems like viewDidLayoutSubviews is the best place to set the frame 

- (void)viewWillLayoutSubviews { 
    [super viewWillLayoutSubviews]; 

    //this will NOT work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 

    //this WILL work 
    self.tableView1.frame = table1LocationWithHeader; 
    self.tableView2.frame = table2LocationWithHeader; 
} 
+0

के लिए tableView.layoutIfNeeded() हो सकता है आप अपने कोड दिखा सकता है? – Nekto

+2

संभावित डुप्लिकेट [UIViewController अमान्य फ्रेम देता है?] (Http://stackoverflow.com/questions/9539676/uiviewcontroller-returns-invalid-frame) –

+0

एनबी! आपका व्यूविल्लएपियर कॉल '[सुपर व्यूडिडएपियर];' यह कॉपी-पेस्ट गलती की तरह दिखता है। – Speakus

उत्तर

93

viewDidLoad कहा जाता है। एक बार सभी ui तत्व को इंटिलाइज्ड और खींचा गया दृश्य DidAppear कहा जाता है।

viewDidLoad - नियंत्रक के दृश्य के बाद कहा जाता है स्मृति

में लोड किया जाता है इस बिंदु दृश्य, दृश्य पदानुक्रम के भीतर नहीं है पर।

viewWillAppear - दृश्य नियंत्रक को सूचित करता है कि इसका दृश्य दृश्य पदानुक्रम में जोड़ा जा रहा है।

फिर से, दृश्य दृश्य पदानुक्रम में अभी तक जोड़ा जाना बाकी है।

viewDidAppear - दृश्य नियंत्रक को सूचित करता है कि इसका दृश्य दृश्य पदानुक्रम में जोड़ा गया था।

केवल दृश्य पदानुक्रम में दृश्य जोड़ा गया है।

अद्यतन

viewDidLayoutSubviews इससे पहले कि यह वास्तव में स्क्रीन पर दिखाई देता यूआई संशोधित करने के लिए सबसे उपयुक्त जगह है।

viewDidLayoutSubviews - दृश्य नियंत्रक को सूचित करता है कि इसके विचार ने अभी इसके सबव्यूशन निर्धारित किए हैं।

+0

ठीक है तो देखेंDidLoad और viewWillAppear फ्रेम को संशोधित करने का प्रयास करने के लिए बस गलत जगह है। हो सकता है कि फ़्रेम सेट करने के लिए सही जगह वास्तव में दृश्य में है/DidLayoutSubviews जो मैंने रॉब द्वारा लिंक किए गए प्रश्न में देखा था, क्योंकि viewDidAppear फ्रेम को संशोधित करने में बहुत देर हो रही है। मैं इसे आज़माउंगा और देख सकता हूं कि यह काम करता है या नहीं। – nacross

+8

मैंने अभी इसे आज़माकर देखा है कि फ्रेम सेट करने के लिए डिडलेआउट सबव्यूव्स सबसे अच्छी जगह की तरह दिखता है। मुझे इसे साफ़ करने में मदद करने के लिए धन्यवाद। – nacross

+0

यह वास्तव में समझा नहीं जाता है कि 'viewDidLoad' में फ्रेम मान सेटिंग क्यों काम नहीं करती है। मैं वास्तव में 'viewDidLoad' में फ़्रेम सेट कर रहा हूं, अक्सर इसे कभी भी कोई समस्या नहीं होती। – Sulthan

2

इस सूत्र देखें When is layoutSubviews called?
उपयोग autolayout, ढांचे स्वचालित रूप से layoutSubviews फोन नहीं करते हैं। यह बहुत महत्वपूर्ण है।रेफरी से:

  • init layoutSubviews का कारण नहीं है (डुह)
  • addSubview के नाम से जाना: layoutSubviews दृश्य पर कहा जा करने के लिए जोड़ा जा रहा है, दृश्य यह (लक्ष्य दृश्य) में जोड़ा जा रहा है, और कारण बनता है सब लक्ष्य के सबव्यूज। ...


आप viewDidLoad में subview जोड़ते हैं, तो layoutSubviews viewDidAppear से पहले कहा जाता है, और आप subviews के सही आकार मिल सकती है। लेकिन अगर आप कुछ भी नहीं करते हैं, तो viewDidviews को ViewDidAppear के बाद बुलाया जाएगा। यह आपके कोड पर निर्भर है।

0
viewWillAppear में

()

सिर्फ दृश्य जिसका फ्रेम आप प्राप्त करना चाहते हैं के लिए layoutIfNeeded (कहते हैं) एक बार।

अगर tableView तो exmple

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