iphone - आईओएस: ऑटो लेआउट में मल्टी-लाइन UILabel




ios cocoa-touch (6)

मुझे ऑटो लेआउट के साथ कुछ बहुत ही बुनियादी लेआउट व्यवहार प्राप्त करने की कोशिश करने में परेशानी हो रही है। मेरा दृश्य नियंत्रक आईबी में ऐसा दिखता है:

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

स्ट्रिंग द्वारा आवश्यक लाइनों की संख्या फिट करने के लिए मुझे आकार बदलने के लिए शीर्षक लेबल कैसे प्राप्त किया जा सकता है? मेरी समझ यह है कि मैं setFrame विधियों का उपयोग नहीं कर सकता क्योंकि मैं ऑटो लेआउट का उपयोग कर रहा हूं। और मुझे ऑटो लेआउट का उपयोग करना होगा क्योंकि मुझे शीर्षक लेबल (इसलिए बाधाओं) के नीचे रहने के लिए उन अन्य विचारों की आवश्यकता है।

मैं यह कैसे कर सकता हूं?


इस विषय पर कई विषयों में पाए गए विभिन्न समाधानों में से कोई भी मेरे मामले के लिए पूरी तरह से काम नहीं करता है (गतिशील तालिका दृश्य कक्षों में एक्स गतिशील मल्टीलाइन लेबल)।

मुझे ऐसा करने का एक तरीका मिला:

अपने लेबल पर बाधाओं को सेट करने के बाद और अपनी मल्टीलाइन प्रॉपर्टी को 0 पर सेट करने के बाद, UILabel का उप-वर्ग बनाएं; मैंने अपना ऑटोलाउट लेबल कहा:

@implementation AutoLayoutLabel

- (void)layoutSubviews{
    [self setNeedsUpdateConstraints];
    [super layoutSubviews];
    self.preferredMaxLayoutWidth = CGRectGetWidth(self.bounds);
}

@end

ऐसा करने का एक तरीका ... पाठ की लंबाई बढ़ने के साथ लेबल टेक्स्ट के फ़ॉन्ट्स को बदलने (घटाने) को बदलने का प्रयास करें

Label.adjustsFontSizeToFitWidth = YES;

मुझे लगता है कि आपको निम्न की आवश्यकता है:

  • एक शीर्ष बाधा
  • एक अग्रणी बाधा (जैसे बाएं तरफ)
  • एक पिछली बाधा (जैसे दाहिने तरफ)
  • कम से कम क्षैतिज सामग्री को प्राथमिकता से सेट करें, इसलिए टेक्स्ट छोटा होने पर यह दी गई जगह भर जाएगी।
  • सामग्री संपीड़न प्रतिरोध सेट करें, क्षैतिज कम, इसलिए यह व्यापक बनने की कोशिश के बजाय लपेट जाएगा।
  • लाइनों की संख्या 0 पर सेट करें।
  • शब्द लपेटने के लिए लाइन ब्रेक मोड सेट करें।

मेरे पास UITableViewCell है जिसमें एक टेक्स्ट रैप लेबल है। मैंने निम्नानुसार टेक्स्ट रैपिंग काम किया।

1) इस प्रकार UILabel बाधाओं को सेट करें।

2) सेट नंबर। 0 के लिए लाइनों के।

3) UITableViewCell को UILabel ऊंचाई बाधा जोड़ा गया।

@IBOutlet weak var priorityLabelWidth: NSLayoutConstraint!

4) UITableViewCell पर:

priorityLabel.sizeToFit()
priorityLabelWidth.constant = priorityLabel.intrinsicContentSize().width+5

स्रोत: http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

बहु-पंक्ति पाठ का आंतरिक सामग्री आकार

UILabel और NSTextField का आंतरिक सामग्री आकार मल्टी-लाइन टेक्स्ट के लिए संदिग्ध है। पाठ की ऊंचाई रेखाओं की चौड़ाई पर निर्भर करती है, जो बाधाओं को हल करते समय अभी तक निर्धारित नहीं है। इस समस्या को हल करने के लिए, दोनों वर्गों में पसंदीदा MaxLayoutWidth नामक एक नई संपत्ति होती है, जो आंतरिक सामग्री आकार की गणना के लिए अधिकतम पंक्ति चौड़ाई निर्दिष्ट करती है।

चूंकि हम आमतौर पर इस मूल्य को पहले से नहीं जानते हैं, इसलिए हमें यह अधिकार प्राप्त करने के लिए दो-चरणीय दृष्टिकोण लेने की आवश्यकता है। सबसे पहले हम ऑटो लेआउट को अपना काम करने देते हैं, और फिर हम लेआउट पास में परिणामी फ्रेम का उपयोग पसंदीदा अधिकतम चौड़ाई को अपडेट करने और फिर लेआउट ट्रिगर करने के लिए करते हैं।

- (void)layoutSubviews
{
    [super layoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [super layoutSubviews];
}

लेबल के लिए फ्रेम सेट प्राप्त करने के लिए [सुपर लेआउटसब्यूव्यू] के लिए पहला कॉल आवश्यक है, जबकि परिवर्तन के बाद लेआउट को अपडेट करने के लिए दूसरा कॉल आवश्यक है। अगर हम दूसरी कॉल को छोड़ देते हैं तो हमें एनएसआईएननल इन्फॉन्सिस्टेंसी अपवाद त्रुटि मिलती है, क्योंकि हमने लेआउट पास में बदलाव किए हैं, जिन्हें बाधाओं को अपडेट करने की आवश्यकता है, लेकिन हमने फिर से लेआउट ट्रिगर नहीं किया।

हम इसे एक लेबल सबक्लास में भी कर सकते हैं:

@implementation MyLabel
- (void)layoutSubviews
{
    self.preferredMaxLayoutWidth = self.frame.size.width;
    [super layoutSubviews];
}
@end

इस मामले में, हमें पहले [सुपर लेआउटसब्यूव्यू] को कॉल करने की आवश्यकता नहीं है, क्योंकि जब लेआउटस्यूब्यूव्स को कॉल किया जाता है, तो हमारे पास लेबल पर पहले से ही एक फ्रेम होता है।

दृश्य नियंत्रक स्तर से यह समायोजन करने के लिए, हम viewDidLayoutSubviews में हुक करते हैं। इस बिंदु पर पहले ऑटो लेआउट पास के फ्रेम पहले से ही सेट हैं और हम उन्हें पसंदीदा अधिकतम चौड़ाई निर्धारित करने के लिए उपयोग कर सकते हैं।

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
    [self.view layoutIfNeeded];
}

अंत में, सुनिश्चित करें कि आपके पास उस लेबल पर स्पष्ट ऊंचाई बाधा नहीं है जिसकी लेबल की सामग्री संपीड़न प्रतिरोध प्राथमिकता की तुलना में उच्च प्राथमिकता है। अन्यथा यह सामग्री की गणना की ऊंचाई को ट्रम्प करेगा। लेबल की ऊंचाई को प्रभावित करने वाली सभी बाधाओं को जांचना सुनिश्चित करें।


UILabel और autolayout पर -setPreferredMaxLayoutWidth उपयोग बाकी को संभालना चाहिए।

[label setPreferredMaxLayoutWidth:200.0];

UILabel दस्तावेज देखें।

अद्यतन करें:

केवल स्टोरीबोर्ड में ऊंचाई की बाधा को ग्रेटर से बराबर या बराबर करने की आवश्यकता है ", सेट करने की कोई ज़रूरत नहीं है MaxLayoutWidth।







autolayout