2012-06-29 12 views
21

NSSplitView सबव्यू के अंदर ऑटो लेआउट बाधाओं का उपयोग कैसे करना चाहिए?NSSplitView और autolayout

मेरे NSSplitView subview 3 subview है: topPane, tableContainer और bottomPane और मैं इस तरह constrains सेट:

NSDictionary* views = NSDictionaryOfVariableBindings(topPane, tableContainer, bottomPane); 

for (NSView* view in [views allValues]) { 
    [view setTranslatesAutoresizingMaskIntoConstraints:NO]; 
} 

[myView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topPane(34)][tableContainer][bottomPane(24)]|" 
                   options:0 
                   metrics:nil 
                   views:views]]; 

[mySplitView addSubview:myView]; 

और कंसोल में इस मिल गया:

Unable to simultaneously satisfy constraints: 
(
    "<NSLayoutConstraint:0x7fd6c4b1f770 V:[NSScrollView:0x7fd6c4b234c0]-(0)-[CPane:0x7fd6c4b2fd10]>", 
    "<NSLayoutConstraint:0x7fd6c4b30910 V:[CPane:0x7fd6c4b2f870(34)]>", 
    "<NSLayoutConstraint:0x7fd6c4b30770 V:|-(0)-[CPane:0x7fd6c4b2f870] (Names: '|':NSView:0x7fd6c4b22e50)>", 
    "<NSLayoutConstraint:0x7fd6c4b212f0 V:[CPane:0x7fd6c4b2fd10]-(0)-| (Names: '|':NSView:0x7fd6c4b22e50)>", 
    "<NSLayoutConstraint:0x7fd6c4b2f910 V:[CPane:0x7fd6c4b2f870]-(0)-[NSScrollView:0x7fd6c4b234c0]>", 
    "<NSLayoutConstraint:0x7fd6c4b21290 V:[CPane:0x7fd6c4b2fd10(24)]>", 
    "<NSAutoresizingMaskLayoutConstraint:0x7fd6c3630430 h=--& v=--& V:[NSView:0x7fd6c4b22e50(0)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fd6c4b1f770 V:[NSScrollView:0x7fd6c4b234c0]-(0)-[CPane:0x7fd6c4b2fd10]> 

मैं <NSAutoresizingMaskLayoutConstraint:0x7fd6c3630430 h=--& v=--& V:[NSView:0x7fd6c4b22e50(0)]> इस का कारण बनता है लगता है, लेकिन मैं ऑटोरेसाइजिंग मास्क रीसेट नहीं कर सकता, क्योंकि NSSplitView इसे सेट करता है।

विभाजन दृश्य के अंदर ऑटो लेआउट का उपयोग करने का सबसे अच्छा तरीका क्या है? और NSSplitViewDelegate के बिना ऑटो लेआउट के साथ विभाजित दृश्य सबव्यू के न्यूनतम/अधिकतम आकार को संभालने का कोई तरीका है?

+0

वही समस्या यहां। मैंने प्रोग्रामेटिक रूप से आईबी में सबकुछ बाहर रखा है, लेकिन 'एनएसयूयूटोर्सिज़िंग मास्कलेआउट कॉन्स्ट्रेन' सहित समान डिबगिंग आउटपुट है। –

+1

यह 10.8 के तहत तय लगता है लेकिन 10.7 के तहत नोट के रूप में टूट गया है। 10.8 में आप एक्सकोड में विभाजित दृश्य के सामग्री दृश्यों की न्यूनतम ऊंचाई और चौड़ाई निर्धारित कर सकते हैं (4.5.2 वैसे भी)। 10.7 के तहत ऐसा नहीं कर सकता है और 10.8 में बनाए गए ऐप्स अभी भी सही काम नहीं करते हैं 10.7 – Dad

+0

सामान्य रूप से 10.8+ के साथ काम करता है लेकिन अधिकांश विचारों के लिए सबव्यू के बीच बाधाओं को निर्दिष्ट करने की आवश्यकता है - नहीं - या आपको * असमर्थ एक साथ * त्रुटि को संतुष्ट करने के लिए .. – Jay

उत्तर

0

मैं बाद में एक निब फ़ाइल और setTranslatesAutoresizingMaskIntoConstraints:NO द्वारा लोड करता हूं।

तो शायद आपको पहले अपने विचारों को [mySplitView addSubview:myView]; जोड़ना चाहिए और बाद में बाधाओं के लिए ऑटोसाइजिंग मास्क के अनुवाद को अक्षम करना चाहिए और इसके बाद आप myView पर अपनी बाधा डाल सकते हैं।

संपादित करें:

ठीक है ऐसा लगता है मैं MyView missunderstand। आपको सबव्यू में बाधा जोड़नी है, न कि स्प्लिटव्यू पर। क्योंकि NSSplitView में subviews पहले से ही autoresizing रहे हैं:

[topPane addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topPane(34)]" options:0 metrics:nil views:views]]; 

[bottomPane addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bottomPane(24)]" options:0 metrics:nil views:views]]; 

आप धार की कमी को जोड़ने की जरूरत नहीं है ("| |" में "[topPane (34)] वी")।

यह इस उदाहरण के लिए नेतृत्व करता है।

Screenshout

नोट:: topPane बाधा के लिए subview सामग्री पर ध्यान न दें, वे तो बस प्लेसहोल्डर

+0

यदि मैं 'myView' के लिए' NO' पर 'translatesAutoresizingMaskIntoConstraints'' सेट करता हूं, तो विभाजित दृश्य इसके आकार को संभाल नहीं पाएगा - यह ऑटोलायआउट के साथ काम नहीं करता है। – Dmitry

1

आप सब पर translatesAutoresizingMaskIntoConstraints निष्क्रिय करने के लिए नहीं करना चाहते हैं। आपको सिस्टम दृश्य बाधाओं के साथ गड़बड़ नहीं करना चाहिए। NSSplitView व्यक्तिगत विचारों के लिए आकार बदलता है और आप अनिवार्य रूप से इसे अपने नियंत्रण को दूर करने की कोशिश कर रहे हैं। उल्लेख नहीं है, आप स्प्लिटर के लिए खाता भूल गए हैं।

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

आप यह सब ठीक से आईबी में कर सकते हैं। आप स्प्लिट व्यू में प्रत्येक दृश्य की प्राथमिकता भी सेट कर सकते हैं, जिससे एक या दूसरे दृश्य का आकार बदलना होगा जब खिड़की आकार को समान रूप से वितरित करने के बजाय करता है।

+0

यह सुनकर दिलचस्प रहें कि आप ऑटोलायआउट के साथ आईबी में ऐसा करने का प्रस्ताव कैसे करते हैं .... – Dad

+0

वास्तव में 10.7 में संभव नहीं है - NSSplitView सामग्री दृश्य पर चौड़ाई बाधा सेट करने के लिए नियंत्रण Xcode 4.5.2 में 10.7 के तहत अक्षम है और यदि आप इसे 10.8 पर एक्सकोड में सेट करते हैं और फिर ऐप को 10.7 पर चलाते हैं तो यह 10.7 में एनएसएयूटोरोसिंग मास्कलेयर कॉन्स्ट्रेनट के पक्ष में उस बाधा को तोड़ देगा और इसलिए काम नहीं करेगा। – Dad

4

एनएसएसप्लिट व्यू शुरुआत के बाद से एक अजीब बात रही है और अगर यह जल्द ही चली जाएगी तो मुझे आश्चर्य नहीं होगा। एक महीने के लिए ऑटोलायआउट के साथ काम कर रहे एनएसएसप्लिट व्यू को प्राप्त करने और एक निराशाजनक हमले से दूसरे में डूबने के बाद, मैंने अंत में छोड़ दिया।

मेरा समाधान पर है NSSplitView का उपयोग ऑटोलाउट के साथ बिल्कुल नहीं। तो NSSplitView के बिना Autolayout या Autolayout के बिना NSSplitView: यह उतना जटिल नहीं है जितना लगता है: बस अपने सबव्यूज़ को एक-दूसरे के बगल में रखें और IBOutlets के रूप में जोड़ें। इन बाधाओं के स्थिरांक को कोड में नियंत्रक से सेट और बदला जा सकता है। उस दृष्टिकोण के साथ आप मूल (नकारात्मक विंडो को विंडो से बाहर स्लाइड करने के लिए), चौड़ाई और अन्य सबव्यू के संबंधों को सेट कर सकते हैं - साथ ही दृश्य के एनिमेटर के साथ बाधाओं को एनिमेट करना वास्तव में आसान है (कभी भी एनिमेट एनएसएसप्लिट व्यू को आजमाया गया है?)

एकमात्र चीज गायब है, जो डिवाइडर पर माउस ड्रैग है, लेकिन इसे आपके कस्टम "स्प्लिट व्यू" में माउस एवेन्ट्स को ट्रैक करने के लिए कुछ लाइनों के साथ कार्यान्वित किया जा सकता है।

ऐप्पल (दुर्भाग्य से केवल लंबवत) से एक ऑटोलायआउट "स्प्लिटव्यू" उदाहरण है और मैंने हाल ही में गिथब पर कम से कम एक नई परियोजना देखी है। हालांकि मेरे लिए, मैंने सोचा कि मेरे ऐप की विशिष्ट ज़रूरतों के लिए मेरे कस्टम समाधान के साथ शुरू करना आसान होगा, बजाय कुछ सार्वभौमिक बनाने की कोशिश करने के बजाय (इस प्रकार इसे संभालने में बहुत जटिल बना दिया जा सकता है)।

संपादित करें: अब मैंने अपना कस्टम विभाजन पूरा किया है जो अलग-अलग निब्स से अपने सबव्यूव लोड करता है। कोई बाधा नहीं, कोई autolayout चेतावनी नहीं। एनएसएसप्लिट व्यू के साथ काम करने की कोशिश करने के पूरे महीने की तुलना में, अब मेरे पास केवल एक शाम में बनाई गई बाधाओं, आसानी से एनिमेटेबल पर आधारित एक कस्टम कस्टम स्प्लिट व्यू है। मैं निश्चित रूप से इस मार्ग को लेने की सलाह देते हैं!

+0

क्या आप अपना कस्टम स्प्लिट व्यू कोड साझा कर सकते हैं? –

+1

@ बेन-उरी: मेरे पास मेरे [उत्तर] (http://stackoverflow.com/a/13964486/456851) में एक छोटी परियोजना है जो आपके लिए उपयोग की जा सकती है। –

+0

बकवास - 10.8+ – Jay

0

जितना मुझे असहमत होने से नफरत है, लेकिन ऑको का जवाब उच्चतम वोट नहीं दिया जाना चाहिए। यह किसी भी तरह की पर्याप्त मात्रा में समस्या को हल करने में सहायक नहीं है। मेरी राय में NSSplitView केवल उन लोगों के लिए एक समस्या थी जिन्होंने दस्तावेज़ीकरण को पर्याप्त रूप से पढ़ा नहीं था।

यहां वर्णित समस्या का वास्तविक समाधान काफी सरल है: ऑटो लेआउट ने NSSplitView पर नई "होल्डिंग प्राथमिकता API" पेश की है। और जैसा कि प्रलेखन कहता है: एक सबव्यू की होल्डिंग प्राथमिकता के लिए निम्न मान निर्धारित करना उसे पहले चौड़ाई लेने की अधिक संभावना देगा। यह सब किसी भी निराशा के बिना आईबी और प्रोग्रामेटिक रूप से सेट किया जा सकता है। आवश्यक काम की मात्रा: लगभग 20 सेकंड।

+1

यह उत्तर अधिक उपयोगी होगा अगर उसने अन्य उत्तरदाताओं और प्रश्नकर्ताओं के लिए इस तरह की अवमानना ​​दिखाने के बजाय प्रश्न का उत्तर दिया। मैं आपको जवाब के लिए +1 और अशिष्टता के लिए -1 दूंगा, इसलिए वे एक-दूसरे को रद्द कर देते हैं। –

+1

@ जैक्यू: यदि आपने दस्तावेज़ीकरण भी पढ़ा था, तो आपने देखा होगा कि होल्डिंग प्राथमिकताएं केवल ओएस एक्स 10.8+ पर काम करती हैं। दूसरों के खिलाफ असंगत होने की कोई आवश्यकता नहीं है जब शायद वे पीछे की संगतता के बारे में सोच रहे थे और आप नहीं थे। –

+1

@ जैक्यू: यदि आप वास्तव में एक साधारण लेआउट से निपट रहे हैं, तो आप सही हो सकते हैं, जैसे दो टेक्स्ट व्यू एक स्प्लिट व्यू के सबव्यूज़ के रूप में। लेकिन जैसे ही आपको जटिल लेआउट किए गए सबव्यूज़ से निपटने की ज़रूरत है, होल्डिंग प्राथमिकताओं को स्थापित करने में बहुत मदद नहीं होगी: एक विभाजन में सामग्री देखें जो ऑटोलायआउट का उपयोग करता है ऑटोटायआउट त्रुटियों को बनाता है क्योंकि यह ऑटोरेसाइजिंग मास्क के साथ संघर्ष करता है। एनिमेटिंग स्प्लिट व्यू बट में दर्द है, क्योंकि आपको फ्रेम की गणना करने की आवश्यकता है, जो ऑटो-लेआउट का उपयोग करते समय नो-गो है। प्राथमिकताओं को रखने के साथ आप वास्तव में बहुत अधिक समस्याएं हल कर सकते हैं। – auco

7

मुझे पता चला यह त्रुटि दिखाई देती है कि अगर मैं इस प्रतिनिधि से किसी भी विधि से मेरी खिड़की और नियंत्रित विभाजन को ध्यान में रखते उपकरण पट्टी है:

यहाँ 10.7 के लिए मेरे समाधान (एक कस्टम विभाजित दृश्य) है:

splitView:constrainMinCoordinate:ofSubviewAt: 
splitView:constrainMaxCoordinate:ofSubviewAt: 
splitView:shouldAdjustSizeOfSubview: 

विंडोडिडलोड में विंडो में टूलबार को जोड़ने में समाधान मिला।

+0

मेरे पास एनएसटीएबी व्यू के साथ एक ही समस्या थी, टूलबार के 'लॉन्च पर दृश्यमान' चेकबॉक्स को अनचेक करना और फिर इसे 'विंडोडिडलोड' में दिखाई देने से बेवकूफ चेतावनियों से छुटकारा पाना पड़ा। संकेत के लिए धन्यवाद। – DarkDust

+0

न्यूनतम/अधिकतम चौड़ाई बाधाओं के साथ एक ऑटो लेआउट-आधारित स्प्लिट दृश्य में मुझे एक ही समस्या थी। इन सभी 3 प्रतिनिधि तरीकों को हटाकर इसे हल किया गया। –

+2

इस प्रश्न पर बहुत सारी गलत जानकारी। यह जवाब सही रास्ते पर है, लेकिन टूलबार व्यवसाय एक लाल हेरिंग है। यह मुद्दा ऐपकिट रिलीज नोट्स (https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKitOlderNotes/index.html#10_11SplitView) में प्रलेखित है; कुछ 'NSSplitViewDelegate' विधियां ऑटोलायआउट के साथ अच्छी तरह से नहीं खेलती हैं और इनका उपयोग नहीं किया जाना चाहिए। इसके बजाय, 'एनएसएसवीट व्यू' के तहत सीधे 'NSView' पर उचित बाधाएं सेट करें, और इसे लॉगिंग के बिना ठीक काम करना चाहिए। – bhaller

3

किसी को जो भविष्य में इस पर लड़खड़ाती है और बाधा आधारित NSSplitView प्रतिस्थापन में एक कूद शुरू की तलाश में है के लिए, मैं एक छोटी परियोजना है कि यहाँ ऑटो लेआउट का उपयोग कर NSSplitView की सुविधाओं के एक हिस्से को पुन: बनाने के लिए प्रयास करता लिखा है:

https://github.com/jwilling/JWSplitView

यह कुछ हद तक गाड़ी है, लेकिन यह इस मार्ग जाना चाहता है किसी के लिए एक उपयोगी संदर्भ हो सकता है।

0

मुझे अपने ऑटोलायआउट को चेतावनियों को साफ करने में कुछ समय लगा लेकिन मुझे इसे आईबी (कई विभाजन और सबव्यू) में संभाला गया।

मेरे लेआउट लगता है:

RootView
    | - 1 NSSplitView (3 खड़ी subviews)
            | ---- UIView (बाएं)
            | ---- 2 NSSplitView (बीच में & 2 क्षैतिज subviews)
                      | --- UIView (ऊपर)
                      | --- 3 NSSplitView (नीचे & 3 लंबवत उपदृश्य)
                              | --- UIView (बाएं)
                              | --- UIView (बीच में)
                              | --- UIView (दाएं)
            | ---- UIView (दाएं)

मेरे समस्या थी, कि मेरे सभी सबव्यूव में 1 9 चेतावनी थी लेकिन मेरा लेआउट ठीक दिखता था और काम करता था कि यह कैसे होना चाहिए। थोड़ी देर के बाद मुझे अपनी चेतावनियों का कारण मिला: मेरे पहले विभाजन में बाहरी विचारों की बाधाएं।

दोनों विचारों (बाएं और दाएं) में "चौड़ाई> = 200" के साथ चौड़ाई-बाधा थी और केंद्र दृश्य (द्वितीय विभाजन) में कोई बाधा नहीं थी (क्योंकि इसकी न्यूनतम चौड़ाई और अधिकतम चौड़ाई जहां इसके सबव्यूज़ द्वारा नियंत्रित की जाती है) ।

चेतावनियों ने मुझे दिखाया कि ऑटोलायआउट मेरे आईबी-यूआई-लेआउट को कम करना चाहता है क्योंकि गणना की गई न्यूनतम चौड़ाई जहां मेरे लेआउट से छोटी है लेकिन मैं इसे आईबी में छोटा नहीं करना चाहता था।

मैंने अपने पहले स्प्लिटव्यू के दोनों बाहरी सबव्यू में एक निश्चित बाधा "चौड़ाई = 200" जोड़ा और "निर्माण समय पर हटाएं" की जांच की।

अब मेरा लेआउट चेतावनियों से मुक्त है और सबकुछ काम करता है कि यह कैसे होना चाहिए।

मेरा निष्कर्ष:

मुझे लगता है कि autolayout और splitviews साथ समस्या यह है कि autolayout subviews के चौड़ाई-बाधाओं को संभाल नहीं कर सकते हैं। कारण हम स्प्लिटव्यू का उपयोग करना चाहते हैं, हम विचारों की गतिशील चौड़ाई चाहते हैं और हम इसे दोनों दिशाओं, सिकुड़ने और विस्तार में चाहते हैं।

तो कोई चौड़ाई < = xxx & & चौड़ाई> = xxx नहीं है। Autolayout केवल इसे संभाल सकता है और हमें आईबी में चेतावनियां मिलती हैं। आप इस समस्या को आईबी में एक अस्थायी बाधा के साथ ठीक कर सकते हैं जो रनटाइम से पहले हटा दिया जाएगा।

मुझे उम्मीद है कि यह समझ में आता है कि मैंने क्या लिखा लेकिन यह मेरी परियोजना में ठीक काम करता है। (Subviews हकलाना मैं जहाँ मैं इस सूत्र पाया आज तक किसी भी समस्या का समाधान नहीं पाया जा सका .. इसलिए मुझे लगता है कि आपकी पोस्ट मुझे :-)

0

प्रेरित मैं एक समाधान के रूप इस वर्ग के लिए प्रयोग किया जाता है, यह सही नहीं है:

पी एस थोड़ा सा) लेकिन यह मुझे अनवरोधित कर दिया। मैं इस वर्ग का उपयोग प्रत्येक स्प्लिट व्यू फलक के अंदर कस्टम क्लास के रूप में करता हूं।

@interface FBSplitPaneView : NSView 

@end 

@implementation FBSplitPaneView 

- (void)setFrame:(NSRect)frame 
{ 
    for (NSView *subview in self.subviews) { 
    subview.frame = self.bounds; 
    } 
    [super setFrame:frame]; 
} 

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