2014-07-07 6 views
6

का उपयोग कर स्वचालित रूप से NSTextField को लपेटें NSTextField के चौड़ाई के रूप में ऑटो-लेआउट स्वचालित रूप से NSTextField को एकाधिक पंक्तियों में कैसे लपेटता है?स्वत: लेआउट

मेरे पास एक इंस्पेक्टर फलक में स्थिर टेक्स्ट (यानी लेबल) प्रदर्शित करने वाले कई NSTextFields हैं। चूंकि इंस्पेक्टर फलक का उपयोग उपयोगकर्ता द्वारा किया जाता है, इसलिए यदि आवश्यक हो तो मैं दाएं हाथ की तरफ लेबल्स को कई लाइनों में रीफ्लो करना चाहूंगा।

(खोजक के प्राप्त जानकारी पैनल करता है।)

लेकिन मैं ऑटो लेआउट की कमी का उचित संयोजन यह पता लगाने की इस व्यवहार अनुमति देने के लिए नहीं कर पाए हैं। सभी मामलों में, सही पर NSTextFields लपेटने से मना कर दिया। (जब तक मैं स्पष्ट रूप से ऊंचाई बाधा नहीं जोड़ता जो इसे अनुमति देता है।)

दृश्य पदानुक्रम ऐसा है कि प्रत्येक ग्रे बैंड एक दृश्य है जिसमें दो एनएसटीक्स्टफिल्ड्स, बाईं ओर संपत्ति का नाम और दाईं ओर संपत्ति मूल्य शामिल है। चूंकि उपयोगकर्ता इंस्पेक्टर फलक का आकार बदलता है, इसलिए मैं प्रॉपर्टी वैल्यू लेबल चाहता हूं कि इसकी आवश्यकता के अनुसार इसकी ऊंचाई को स्वतः आकार दें।

वर्तमान स्थिति:

Text fields not wrapping.

मैं को क्या कहना चाहेंगे होती हैं:

enter image description here

(ध्यान दें कि यह व्यवहार सबसे स्टैक ओवरफ़्लो सवालों से अलग है मैं के बारे में NSTextFields में आए और ऑटो लेआउट। वे प्रश्न चाहते थे कि उपयोगकर्ता टाइपिंग करते समय टेक्स्ट फ़ील्ड बढ़े। इस स्थिति में, टेक्स्ट स्थिर है और NSTextField को देखने के लिए कॉन्फ़िगर किया गया है 1,0

लेने @ hamstergene के सुझाव एक लेबल की तरह।)

अद्यतन, मैं NSTextField subclassed और एक छोटे से नमूना आवेदन किया। अधिकांश भाग के लिए, यह अब काम करता है, लेकिन अब एक छोटा लेआउट मुद्दा है जो मुझे संदेह है कि एनएसटीक्स्टफिल्ड के फ्रेम का नतीजा पूरी तरह से सिंक हो रहा है कि ऑटो-लेआउट की अपेक्षा क्या है। नीचे दिए गए स्क्रीनशॉट में, दाईं ओर वाले पक्ष लेबल सभी top बाधा के साथ लंबवत स्थान पर हैं। जैसे ही विंडो का आकार बदलता है, Where फ़ील्ड ठीक से आकार बदलकर लपेटा जा रहा है। हालांकि, Kind टेक्स्ट फ़ील्ड तब तक धक्का नहीं दिया जाता जब तक कि मैं "एक और पिक्सेल" विंडो का आकार बदलता नहीं हूं।

enter image description here उदाहरण: अगर मैं सिर्फ सही चौड़ाई Where पाठ फ़ील्ड यह पहली चादर है करता है कि करने के लिए विंडो का आकार बदलने, तो मैं बीच छवि में परिणाम प्राप्त। यदि मैं विंडो को एक और पिक्सेल का आकार बदलता हूं, तो Kind फ़ील्ड का लंबवत स्थान ठीक से सेट किया गया है।

मुझे संदेह है कि ऐसा इसलिए है क्योंकि ऑटो-लेआउट यह पास कर रहा है और फिर फ्रेम स्पष्ट रूप से सेट हो रहे हैं। मुझे लगता है कि ऑटो लेआउट उस पास पर नहीं देखता है, लेकिन यह अगले पास पर करता है, और तदनुसार पदों को अपडेट करता है।

मान लीजिए कि यह समस्या है, मैं setFrameSize में इन परिवर्तनों के ऑटो-लेआउट को कैसे सूचित करूं ताकि यह फिर से लेआउट चला सके। (और, सबसे महत्वपूर्ण बात यह है कि लेआउट-सेटफ्रेम आकार-लेआउट-आदि के रिकर्सिव स्थिति में पकड़ा नहीं गया है ...)

समाधान

मैं एक समाधान काम करने के लिए मैं वास्तव में यह कैसे उम्मीद कर रही थी प्रतीत होता है कि ले कर आए हैं। NSTextField subclassing के बजाय, मैं NSTextField के superview में layout को ओवरराइड करता हूं। layout के भीतर, मैंने टेक्स्ट फ़ील्ड पर preferredMaxLayoutWidth सेट किया और फिर एक लेआउट पास ट्रिगर किया। यह ज्यादातर काम करने के लिए पर्याप्त प्रतीत होता है, लेकिन यह लेआउट के कष्टप्रद मुद्दे को संक्षेप में "गलत" छोड़ देता है। (ऊपर नोट देखें)।

इसका समाधान setNeedsDisplay पर कॉल करना प्रतीत होता है और फिर सबकुछ बस काम करता है।

- (void)layout { 
     NSTextField *textField = ...; 
     NSRect oldTextFieldFrame = textField.frame; 

     [textField setPreferredMaxLayoutWidth:NSWidth(self.bounds) - NSMinX(textField.frame) - 12.0]; 

     [super layout]; 

     NSRect newTextFieldFrame = textField.frame; 
     if (oldTextFieldFrame.size.height != newTextFieldFrame.size.height) { 
     [self setNeedsDisplay:YES]; 
     } 
    } 

उत्तर

4

तो निरीक्षक फलक चौड़ाई कभी नहीं बदल जाएगा, बस "सबसे पहले क्रम लेआउट चौड़ाई" आईबी में (ध्यान दें यह 10.8+ सुविधा है) की जाँच करें।

लेकिन इंस्पेक्टर को एक ही समय में परिवर्तनीय चौड़ाई रखने की इजाजत देना अकेले बाधाओं के साथ हासिल करना संभव नहीं है। इसके बारे में ऑटोलाउट में कहीं कमजोर बिंदु है।

मैं इस तरह पाठ क्षेत्र उपवर्गीकरण द्वारा विश्वसनीय व्यवहार को प्राप्त करने में सक्षम था: उच्च ऊर्ध्वाधर गले:

- (NSSize) intrinsicContentSize; 
{ 
    const CGFloat magic = -4; 

    NSSize rv; 
    if ([[self cell] wraps] && self.frame.size.height > 1) 
     rv = [[self cell] cellSizeForBounds:NSMakeRect(0, 0, self.bounds.size.width + magic, 20000)]; 
    else 
     rv = [super intrinsicContentSize]; 
    return rv; 
} 

- (void) layout; 
{ 
    [super layout]; 
    [self invalidateWordWrappedContentSizeIfNeeded]; 
} 

- (void) setFrameSize:(NSSize)newSize; 
{ 
    [super setFrameSize:newSize]; 
    [self invalidateWordWrappedContentSizeIfNeeded]; 
} 

- (void) invalidateWordWrappedContentSizeIfNeeded; 
{ 
    NSSize a = m_previousIntrinsicContentSize; 
    NSSize b = self.intrinsicContentSize; 
    if (!NSEqualSizes(a, b)) 
    { 
     [self invalidateIntrinsicContentSize]; 
    } 
    m_previousIntrinsicContentSize = b; 
} 

या तो मामले में, की कमी स्पष्ट तरीका है (आप शायद पहले से ही यह कोशिश की है) सेट किया जाना चाहिए प्राथमिकता, कम क्षैतिज, पर्यवेक्षण और/या भाई के दृश्यों के लिए सभी चार किनारों को पिन करें।

- (void)viewDidLayout { 
    [super viewDidLayout]; 
    self.aTextField.preferredMaxLayoutWidth = self.aTextField.frame.size.width; 
    [self.view layoutSubtreeIfNeeded]; 
} 

यह केवल बाधा प्रणाली चौड़ाई के लिए हल (ऊंचाई यह रन पर समाधान के अयोग्य हो जाएगा करने देता है:

+0

निरीक्षक की चौड़ाई चर रहा है और उपयोगकर्ता नियंत्रित है। यह किसी भी बाधाओं को नियंत्रित नहीं करता है (न ही परिभाषित)। स्क्रीनशॉट में केवल ग्रे व्यू और NSTextField लेबल ऑटो लेआउट का उपयोग कर रहे हैं। (और यह सब कोड में किया गया है, इंटरफ़ेस बिल्डर में नहीं।) मैं उप-वर्गीकरण को फिर से देखूंगा और मैन्युअल रूप से 'लेआउट' में लेआउट कर रहा हूं, लेकिन मैं केवल बाधाओं का उपयोग करके फाइंडर के गेट इन्फो पैनल में देखे गए रैपिंग व्यवहार को कम करने की उम्मीद कर रहा था। – kennyc

+1

अंत में, setPreferredMaxLayoutWidth स्थान पर समाधान प्राप्त करने की कुंजी थी – kennyc

+0

"पहली रनटाइम लेआउट चौड़ाई" मेरे लिए चाल थी। – dkrdennis

7

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

कोई सबक्लासिंग नहीं, दृश्य के लेआउट विधियों के साथ कोई मैकिंग नहीं, कोई सूचना नहीं। यदि आप NSViewController का उपयोग नहीं कर रहे हैं तो आप इस समाधान को ट्विक कर सकते हैं ताकि यह ज्यादातर मामलों में काम कर सके (पाठ क्षेत्र को उपclassing, कस्टम दृश्य में इत्यादि)।

इनमें से अधिकांश सूजन http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html से आया (मल्टी-लाइन टेक्स्ट सेक्शन का आंतरिक सामग्री आकार देखें)।

1

में खंड पाठ फ़ील्ड पसंदीदा चौड़ाई आकार निरीक्षक टैब में सेट "सबसे पहले क्रम लेआउट चौड़ाई"