2009-07-25 9 views
43

layoutIfNeeded कब और कैसे उपयोग किया जाता है? मुझे पता है कि जब हम दृश्य के लेआउट को बदलते हैं, तो हम लेआउट को अपडेट करने के लिए setNeedsLayout पर कॉल कर सकते हैं लेकिन यह सुनिश्चित नहीं करते कि layoutIfNeeded का उपयोग कब किया जाना चाहिए।लेआउट का उपयोग कैसे किया जाता है?

नोट: मेरे पास layoutIfNeeded वास्तविक कोड में उपयोग किया गया है लेकिन इसका उपयोग किस संदर्भ में किया गया था भूल गया।

उत्तर

57

layoutIfNeeded रिसीवर को आवश्यक होने पर तत्काल अपने सबव्यूज़ लेआउट करने के लिए मजबूर करता है।

मान लीजिए कि आपने layoutSubviews ओवरराइड किया है, और UIKit का मानना ​​है कि आपके दृश्य को किसी भी कारण से लेआउट की आवश्यकता है (उदाहरण के लिए आपने कुछ उपयोगकर्ता कार्रवाई को संभालने पर setNeedsLayout कहा)। फिर, आपकी कस्टम layoutSubviews विधि को सामान्य रूप से नियमित UIKit रन लूप ईवेंट अनुक्रम (ईवेंट हैंडलिंग के बाद, लेकिन drawRect: से पहले) में सामान्य रूप से कॉल करने के बजाए तुरंत कॉल किया जाएगा।

कारण है कि आप एक भी रन पाश के भीतर layoutIfNeeded कॉल करने के लिए आवश्यकता हो सकती है का एक उदाहरण:

  1. आप एक कस्टम लेआउट के साथ एक तालिका दृश्य युक्त एक कस्टम दृश्य का आकार बदलें। setNeedsLayout सेट किया गया है ताकि layoutSubviews बाद में कॉल किया जाएगा।
  2. एक नियंत्रक ऑब्जेक्ट उपयोगकर्ता ईवेंट को संभालने के दौरान किसी विशेष सेल पर स्क्रॉल करने के लिए तालिका दृश्य से पूछता है।
  3. आपका कस्टम व्यू तालिका दृश्य के कुछ कस्टम आकार को layoutSubviews में करता है जो तालिका दृश्य आकार को बदलता है।

समस्या तब होती है जब नियंत्रक ने तालिका दृश्य को स्क्रॉल करने के लिए कहा (चरण 2), तालिका दृश्य में बाध्य थे। अपडेट की गई सीमा केवल बाद में तालिका दृश्य पर सेट की जाएगी (चरण 3)। नियंत्रक चाहता था कि तालिका दृश्य को स्क्रॉल करने के लिए वास्तव में layoutSubviews के बाद दिखाई नहीं दे रहा है। एक समाधान तब नियंत्रक के लिए layoutIfNeeded पर स्थितियों में कॉल करेगा जहां यह जानता है कि यह हो सकता है।

-9

setNeedsLayout वास्तव में लेआउट को कॉल करता है IFNeeded, इसलिए यदि आपके कॉलिंग सेट नेड्स डिस्प्ले को लेआउट कॉल करने का कोई कारण नहीं है IFNeeded। इस तरह setNeedsLayout लेआउट को कॉल करने के लिए एक सुविधाजनक तरीका है IFNeeded जो भारी भारोत्तोलन करता है।

+14

यह सच नहीं है। setNeedsLayout लेआउट के लिए दृश्य को ध्वजांकित करेगा जिसके परिणामस्वरूप लेआउटस्यूव्यूव्स को दूसरे रनलोप चक्र पर कॉल किया जा रहा है। कॉलिंग लेआउट IfNeeded के परिणामस्वरूप लेआउटस्यूव्यूव्स को उसी रनलोप चक्र में बुलाया जा रहा है। इस सेट को लेआउटस्यूव्यूज़ में ब्रेकपॉइंट और फिर सेट्स सेटआउट सेट करने के लिए कॉल पर ब्रेकपॉइंट का परीक्षण करने के लिए। यदि आप एक पंक्ति अग्रिम करते हैं तो आप देखेंगे कि आप लेआउट सबव्यूव में नहीं तोड़ते हैं। हालांकि, यदि आप लेआउट पर तोड़ते हैं IFNeeded और एक लाइन अग्रिम करें, तो आप देखेंगे कि आप लेआउट में तोड़ेंगे आगे बढ़ने से पहले सबव्यूव्यू। – tyler

+1

डांग, क्या एक बड़ा downvote –