2012-06-28 22 views
17

मेरे ऐप में NSScrollView है जिसमें दस्तावेज़ दस्तावेज़ में लंबवत स्टैक्ड NSTextViews शामिल हैं - जिनमें से प्रत्येक वर्टिकल दिशा में आकार बदलता है क्योंकि टेक्स्ट जोड़ा जाता है।एनएसटीएक्स्टव्यू का विस्तार करने के साथ ऑटोलायआउट का उपयोग

वर्तमान में, यह सब कोड में प्रबंधित है। NSTextViews स्वचालित रूप से आकार बदलता है, लेकिन मैं NSViewFrameDidChangeNotification के साथ उनका आकार बदल रहा हूं, अपनी सभी उत्पत्ति को पुन: खोलता हूं ताकि वे ओवरलैप न करें और उनके पर्यवेक्षण (स्क्रॉल व्यू के दस्तावेज़ दृश्य) का आकार बदल सकें ताकि वे सभी फिट हो जाएं और स्क्रॉल किए जा सकें।

ऐसा लगता है कि यह ऑटोलायआउट के लिए एक आदर्श उम्मीदवार होगा! मैंने पहले टेक्स्ट व्यू और उसके कंटेनर, अंतिम टेक्स्ट व्यू और उसके कंटेनर के बीच NSLayoutConstraints सेट किया है, और एक-दूसरे के बीच प्रत्येक टेक्स्ट व्यू सेट किया है। फिर, यदि कोई टेक्स्ट व्यू बढ़ता है, तो यह स्वचालित रूप से बाधाओं को पूरा करने के लिए नीचे दिए गए टेक्स्ट दृश्यों की उत्पत्ति को "नीचे चलाता है", अंत में दस्तावेज़ दृश्य के आकार को बढ़ाता है, और सभी खुश हैं!

इसके अलावा, ऐसा लगता है कि NSTextView स्वचालित रूप से बढ़ने का कोई तरीका नहीं है क्योंकि टेक्स्ट बाधाओं-आधारित लेआउट में जोड़ा जाता है? सटीक उसी NSTextView का उपयोग करके जो टेक्स्ट के रूप में स्वचालित रूप से विस्तारित किया गया था, अगर मैं इसकी ऊंचाई के लिए बाधा निर्दिष्ट नहीं करता हूं, तो यह 0 तक डिफॉल्ट करता है और दिखाया नहीं जाता है। यदि मैं एक बाधा निर्दिष्ट करता हूं, यहां तक ​​कि असमानता जैसे कि = = 20, यह उस आकार पर फंस गया रहता है और पाठ के रूप में नहीं बढ़ता है।

मुझे संदेह है कि इसे -intrinsicContentSize के एनएसटीक्स्टव्यू के कार्यान्वयन के साथ करना है, जो डिफ़ॉल्ट रूप से (NSViewNoInstrinsicMetric, NSViewNoInstrinsicMetric) देता है।

तो मेरे प्रश्न: यदि मैं NSTextView को अपने टेक्स्ट के लेआउट के आधार पर एक और सार्थक intrinsicContentSize वापस करने के लिए उपclasses करता हूं, तो क्या मेरा ऑटोलाउटआउट अपेक्षित काम करेगा?

लंबवत आकार बदलने वाले NSTextView के लिए intrinsicContentSize को लागू करने पर कोई संकेतक?

+0

है का विस्तार होगा आप जोड़ सकते है कुछ ग्राफिक/स्क्रीनशॉट/कृपया सेटअप को समझने के लिए वायरफ्रेम कृपया? क्या आपने टेक्स्ट ऊंचाई की गणना करने और इसे 'intrinsicContentSize' में वापस करने का प्रयास किया था? – JJD

उत्तर

10

मुझे एनएसटीक्स्टफिल्ड के साथ एक ही समस्या थी, और यह पता चला कि यह लंबवत अभिविन्यास के साथ अपनी टेक्स्ट सामग्री को गले लगाने के इच्छुक दृश्य के कारण था। इसलिए यदि आप अपनी अन्य बाधाओं की प्राथमिकताओं की तुलना में कम से कम कुछ सामग्री को प्राथमिकता देते हैं, तो यह काम कर सकता है। उदा .:

[textView setContentHuggingPriority:NSLayoutPriorityFittingSizeCompression-1.0 forOrientation:NSLayoutConstraintOrientationVertical]; 
+0

यह मिलकर बहुत खुशी हुई। मैंने पाया कि मुझे इसे 'NSSplitView' में लंबवत-संरेखित' NSTextField 'के लिए करना था, लेकिन केवल तभी जब वे चयन योग्य और संपादन योग्य नहीं थे! इतना अजीब है कि संपादन व्यवहार प्रभाव बाधाओं को प्रभावित करता है, लेकिन वहां आप जाते हैं। मैंने उनमें से प्रत्येक के लिए 250 से 24 9 तक क्षैतिज सामग्री-छेड़छाड़ प्राथमिकता बदल दी और समस्या दूर हो गई। – theory

+0

स्विफ्ट 4 के तहत यह 'सेटकंटेंटहगिंग प्राइरिटी (एनएसएलएआउट कॉन्स्ट्रेनेंट.प्रिओरिटी.फिटिंग साइज कॉम्प्रेशन' के लिए प्रतीत होता है: NSLayoutConstraint.Orientation.vertical) ' सुनिश्चित नहीं है कि -1 का अर्थ क्या था लेकिन ऐसा लगता है कि यह बिना काम करता है। धन्यवाद, मार्क! –

18

मैं एक बहुत ही इसी तरह के सेटअप पर काम कर रहा हूँ - अपने पाठ सामग्री फिट और autolayout उपयोग करने के लिए विस्तार है कि पाठ विचारों से युक्त विचारों का एक ऊर्ध्वाधर ढेर।

अब तक मैं NSTextView है, जो साफ महसूस नहीं करता है उपवर्ग करना पड़ा है, लेकिन व्यवहार में शानदार काम करता है:

- (NSSize) intrinsicContentSize { 
    NSTextContainer* textContainer = [self textContainer]; 
    NSLayoutManager* layoutManager = [self layoutManager]; 
    [layoutManager ensureLayoutForTextContainer: textContainer]; 
    return [layoutManager usedRectForTextContainer: textContainer].size; 
} 

- (void) didChangeText { 
    [super didChangeText]; 
    [self invalidateIntrinsicContentSize]; 
} 

जब addSubview के साथ जोड़ा पाठ को देखने के प्रारंभिक आकार दिलचस्प है, नहीं आंतरिक आकार; मैंने अभी तक यह पता नहीं लगाया है कि पहली अमान्यता को कैसे जारी किया जाए (हुकिंग viewDidMoveToSuperview मदद नहीं करता है), लेकिन मुझे यकीन है कि मैं इसे अंततः समझूंगा।

+2

बहुत उपयोगी! अपने निष्कर्ष साझा करने के लिए धन्यवाद! – jemmons

+1

नोट: मैं वर्तमान में आकार को आसानी से एनिमेट करने का प्रयास कर रहा हूं, और प्रयोग कर रहा हूं कि क्या मैं इसके बजाय ऊंचाई को नियंत्रित करने के लिए ऑटोलायआउट का उपयोग कर सकता हूं (या आंतरिक आकार का पूरक)। यह पता चला है कि आप '[बाधा सेट कॉन्स्टेंट: न्यूहेइट]' कहकर इसे एक नई ऊंचाई देकर एक बाधा को संशोधित कर सकते हैं, जहां 'बाधा' एक बाधा है जो ऊंचाई सेटिंग प्रदान करती है। यह फिलहाल काम करता है, लेकिन 'NSTextContainer' के स्वचालित आकार बदलने के साथ संघर्ष करता है, जिसके परिणामस्वरूप झटके लगते हैं। –

3

यहां किसी का विस्तार NSTextView ऑटो लेआउट का उपयोग कर,

  • मैं उपयोग textDidChange
  • ऑटो लेआउट के लिए Anchors इस्तेमाल किया NSTextDelegate से बनाने के लिए स्विफ्ट 3 enter image description here

    में है।NSTextViewDelegateNSTextDelegate
  • के अनुरूप विचार है कि textViewedges की कमी है, जिसका अर्थ है कि जब भी अपने intrinsicContentSize परिवर्तन, वह अपने माता-पिता, जो scrollView

    import Cocoa 
    import Anchors 
    
    class TextView: NSTextView { 
        override var intrinsicContentSize: NSSize { 
        guard let manager = textContainer?.layoutManager else { 
         return .zero 
        } 
    
        manager.ensureLayout(for: textContainer!) 
    
        return manager.usedRect(for: textContainer!).size 
        } 
    } 
    
    class ViewController: NSViewController, NSTextViewDelegate { 
    
        @IBOutlet var textView: NSTextView! 
        @IBOutlet weak var scrollView: NSScrollView! 
        override func viewDidLoad() { 
        super.viewDidLoad() 
    
        textView.delegate = self 
    
        activate(
         scrollView.anchor.top.constant(100), 
         scrollView.anchor.paddingHorizontally(30) 
        ) 
    
        activate(
         textView.anchor.edges 
        ) 
        } 
    
        // MARK: - NSTextDelegate 
        func textDidChange(_ notification: Notification) { 
        guard let textView = notification.object as? NSTextView else { return } 
    
        print(textView.intrinsicContentSize) 
        textView.invalidateIntrinsicContentSize() 
        } 
    }