2013-09-25 11 views
33

पर ऑटोलायआउट के साथ समस्या मुझे xcode 5 प्रोजेक्ट पर ऑटोलायआउट के साथ समस्या हो रही है। मैं एक नेविगेशन नियंत्रक के साथ एक सादा दृश्य नियंत्रक का उपयोग कर रहा हूँ। मेरे पास शीर्ष आधा पर MKMapView है और नीचे आधा पर UITableView है। मैं storyboards का उपयोग कर रहा हूं, और प्रोटोटाइप UITableViewCell कॉन्फ़िगर किया है, लेकिन मैं कोड के माध्यम से बाधाओं को जोड़ रहा हूं। मैंने प्रोटोटाइप में हर नियंत्रण को दोबारा जांच लिया है और वहां कॉन्फ़िगर की गई कोई बाधा नहीं दिख रही है। मेरी समस्या तब होती है जब मैं UITableViewCell के लिए बाधाओं को जोड़ता हूं। मेरे पास कक्षों में निम्न कोड है:UITableViewCell

-(void)updateConstraints { 
    [super updateConstraints]; 
    //first remove old constraints 
    [self removeConstraints:self.constraints]; 
    [self.nameLabel removeConstraints:self.nameLabel.constraints]; 
    [self.addressLabel removeConstraints:self.nameLabel.constraints]; 
    [self.rentableSquareFeetLabel removeConstraints:self.rentableSquareFeetLabel.constraints]; 
    [self.lastSaleAmountLabel removeConstraints:self.lastSaleAmountLabel.constraints]; 
    [self.lastSaleDateLabel removeConstraints:self.lastSaleAmountLabel.constraints]; 
    [self.thumbnailImageView removeConstraints:self.thumbnailImageView.constraints]; 

    //then set up constraints 
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_thumbnailImageView, _nameLabel, _rentableSquareFeetLabel, _lastSaleAmountLabel, _addressLabel, _lastSaleDateLabel); 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_thumbnailImageView(60)]-[_nameLabel(<=200)]-(>=8)-[_rentableSquareFeetLabel]-(>=8)-[_lastSaleAmountLabel]|" options:0 metrics:nil views:viewsDictionary]]; 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_nameLabel]-(-4)-[_addressLabel]" options:NSLayoutFormatAlignAllLeading metrics:nil views:viewsDictionary]]; 
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_lastSaleAmountLabel]-(-4)-[_lastSaleDateLabel]" options:NSLayoutFormatAlignAllLeading metrics:nil views:viewsDictionary]]; 
} 

मुझे डीबगिंग कंसोल में निम्नलिखित मिल रहा है। अपवाद पहली addConstraints लाइन से ट्रिगर किया जाता है। मैं तो बस उन के माध्यम से जारी रखते हैं तो अंत में सब कुछ, पता चलता है के रूप में यह होना चाहिए के रूप में यह लग रहा है xcode तरह सही बाधा को तोड़ने के लिए चुन रहा है:

2013-09-25 15:07:14.169 PECProperties[32381:a0b] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) (
    "<NSIBPrototypingLayoutConstraint:0x9d56c70 'IB auto generated at build time for view with fixed frame' H:|-(0)-[UIImageView:0x9d558f0](LTR) (Names: '|':UITableViewCellContentView:0x9d55620)>", 
    "<NSIBPrototypingLayoutConstraint:0x9d56d20 'IB auto generated at build time for view with fixed frame' H:[UIImageView:0x9d558f0(60)]>", 
    "<NSIBPrototypingLayoutConstraint:0x9d56d80 'IB auto generated at build time for view with fixed frame' H:|-(78)-[UILabel:0x9d559e0](LTR) (Names: '|':UITableViewCellContentView:0x9d55620)>", 
    "<NSLayoutConstraint:0x9d53830 H:[UIImageView:0x9d558f0]-(NSSpace(8))-[UILabel:0x9d559e0]>") 

Will attempt to recover by breaking constraint <NSIBPrototypingLayoutConstraint:0x9d56d80 'IB auto generated at build time for view with fixed frame' H:|-(78)-[UILabel:0x9d559e0](LTR) (Names: '|':UITableViewCellContentView:0x9d55620)> 

Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 

तीसरे NSIBPrototypingLayoutConstraint देखने के किनारे है और एक के बीच 78 अंक से पता चलता लेबल। यही वह जगह है जहां प्रोटोटाइप मोटे तौर पर स्थित है (और यदि मैं इसे प्रोटोटाइप में ले जाता हूं, तो मुझे डिबगिंग कंसोल में बाधा में परिवर्तन दिखाई देता है), लेकिन यह छवि दृश्य और लेबल के बीच "मानक" दूरी की अपनी बाधा के साथ संघर्ष करता है ।

मैंने व्यू कंट्रोलर के cellForRowAtIndexPath में translatesAutoresizingMaskIntoConstraints=NO सेट करने का प्रयास किया है, लेकिन ऐसा लगता है कि यह भी मदद नहीं कर रहा है। मैं लेआउट कैसे ठीक कर सकता हूं? यहाँ कवर करने के लिए

+0

मैंने आईओएस 7 में एक-एक-एक बग देखा जो इसी तरह की समस्या का कारण बनता है। मैं आईबी और एक्सकोड में सभी बाधाओं को निर्दिष्ट कर रहा था खुश था। लेकिन अपवाद <सेल ऊंचाई में सभी लंबवत आकारों का योग। समाधान स्वीकार्य था - बिल्ड-टाइम पर बाधाओं में से एक को हटाने के लिए। – Matt

उत्तर

78

कुछ बातें:

  1. NSIBPrototypingLayoutConstraint की कमी है कि आप में चला रहे हैं (और अपवादों उत्पन्न कर रहे हैं कि) स्वत: जनरेट के लिए अपने स्टोरीबोर्ड या XIB दृश्य बनाने के लिए इंटरफ़ेस बिल्डर द्वारा कर रहे हैं लेआउट गैर अस्पष्ट। यह करने के बारे में यह बहुत चुस्त है, लेकिन यह स्वचालित रूप से आवश्यक न्यूनतम बाधाओं को जोड़ रहा है ताकि प्रत्येक अस्पष्ट दृश्य की स्थिति और आकार पूरी तरह निर्दिष्ट हो। यह एक्सकोड 4 से एक बदलाव है, क्योंकि एक्सकोड 4 में इंटरफ़ेस बिल्डर में अस्पष्ट लेआउट नहीं हो सकते हैं। एक्सकोड 5 के साथ और बाद में आप कर सकते हैं, हालांकि यदि आपका लेआउट संकलन समय पर संदिग्ध है तो आईबी आपके लिए इन बाधाओं को स्वतः उत्पन्न करेगा।

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

    Screenshot of the constraint Placeholder checkbox in Xcode 6.

    इतना ही नहीं इस चेकबॉक्स बाधा आपके द्वारा जोड़े को दूर करता है, लेकिन सबसे महत्वपूर्ण बात यह अपनी जगह लेने से स्वत: जनरेट आईबी बाधा नहीं कर पाएगा! (जैसा कि आप कल्पना कर सकते हैं, यह बहुत कठिन है जब आपके पास आईबी में कई विचार हैं और कोड में अपनी सभी बाधाओं को प्रबंधित करना चाहते हैं। इस कारण से आप पूरी तरह से पदानुक्रम देखने के लिए आईबी का उपयोग करने से बच सकते हैं जिसमें आप ऑटो को लागू करना चाहते हैं लेआउट प्रोग्रामेटिक रूप से।)

    प्लेसहोल्डर बाधा और अनइंस्टॉल की गई बाधा के बीच क्या अंतर है?

    Comparison between Placeholder constraints and Uninstalled constraints.

  2. updateConstraints में, आप की कमी दूर करने के लिए नहीं करना चाहते हैं और उन्हें फिर से जोड़ की तरह तुम वहाँ है: यहाँ मेरी Adaptive Auto Layout talk (video) (PDF slides) से एक स्लाइड दो की तुलना है। क्यों नहीं?अनिवार्य रूप से, यह प्रदर्शन के लिए भयानक है, और मैंने ऐप्पल इंजीनियरों के साथ पुष्टि की है कि यह एक अच्छा विचार नहीं है। कुछ और विवरणों के साथ-साथ answer के लिए question/answer I have posted here देखें। बाधाओं को एक से अधिक बार जोड़ने के लिए, एक बूलियन ध्वज (उदाहरण के लिए hasSetupConstraints) का उपयोग करें ताकि आप पहली बार अपनी बाधाओं को स्थापित करने के बाद YES पर सेट कर सकें, और यदि updateConstraints फिर से कॉल किया जाता है तो आप तुरंत वापस लौट सकते हैं यदि आपके पास नहीं है जोड़ने के लिए नई बाधाएं। आगे की चर्चा के लिए this question देखें।

  3. जो कोड आप बाधाओं को दूर करने के लिए उपयोग कर रहे हैं वह पूरी तरह से काम नहीं कर सकता है। ऐसा इसलिए है क्योंकि [view removeConstraints:view.constraints] केवल view में जोड़े गए बाधाओं को हटा देगा - याद रखें कि बाधाओं को उनके विचारों के किसी भी सामान्य पर्यवेक्षण में जोड़ा जा सकता है - और view में जोड़े गए बाधा view के लेआउट को प्रभावित करने वाले एकमात्र व्यक्ति नहीं हो सकते हैं ! यदि आपको कई बाधाओं को दूर करने की आवश्यकता है, तो आपको किसी संपत्ति में उन सभी बाधाओं का संदर्भ देना चाहिए (उदा। एनएसएआरएआरएआर संपत्ति जिसमें एनएसएलएआउट कॉन्स्ट्रेनेंट उदाहरण शामिल हैं), और फिर NSLayoutConstraint या the PureLayout open-source library पर API का उपयोग करके उन बाधाओं को निष्क्रिय/हटा दें। आपको केवल कुछ बाधाओं को निष्क्रिय/हटा देना चाहिए क्योंकि यह ऐसा करने के लिए कम्प्यूटेशनल रूप से महंगा है। दूसरी तरफ, किसी भी बाधा के constant को बदलना बहुत ही कुशल और प्रोत्साहित है, और आपको ऐसा करने के लिए बाधा को हटाने या फिर से जोड़ने की आवश्यकता नहीं है।

+0

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

+0

कोई समस्या नहीं है। यदि आप आईबी से अच्छी तरह से काम कर रहे बाधाओं को प्राप्त कर सकते हैं, तो इसके लिए जाएं। लेकिन व्यक्तिगत रूप से मैंने मूल रूप से आईबी का उपयोग बंद कर दिया है, खासकर जब ऑटो लेआउट की बात आती है। आईबी भ्रामक रूप से सरल दिख रहा है लेकिन किसी भी चीज के लिए इतना दर्द पैदा कर सकता है लेकिन दृश्य सेटअप के सबसे सरल (अक्सर, जो आप देखते हैं ** ** नहीं है ** आपको क्या मिलता है!)। वैसे भी ... यह पूछने में संकोच न करें कि क्या आप किसी अन्य ठोकरें ब्लॉक में चले जाते हैं। – smileyborg

+0

मुझे समझ में नहीं आता कि आपका क्या मतलब है "न केवल यह चेकबॉक्स आपके द्वारा जोड़े गए बाधा को हटाता है" आप अभी भी एक बाधा को क्यों हटाना चाहते हैं? – drc