2012-11-14 11 views
46

के लिए ऑटो-लेआउट बाधाओं को हटाएं मेरे पास UIImageViewUIView में एम्बेडेड है। मेरा पूरा ऐप AutoLayout का उपयोग करता है, लेकिन मैं के लिए constraints को हटाना चाहता हूं। Xcode मुझे constraints हटाने की अनुमति नहीं देगा, क्या उन्हें किसी विशिष्ट वस्तु के लिए अक्षम करने का कोई तरीका है, उन्हें शून्य पर सेट करें, कुछ?विशिष्ट ऑब्जेक्ट

+0

यदि आप बाधाओं को हटाते हैं, तो छवि दृश्य कैसे प्रदर्शित किया जा सकता है? लेआउट इंजन को यह कहां रखा जाए कि इसे कहां रखा जाए? पूरे दृश्य को स्पष्ट रूप से प्रस्तुत करने के लिए आपके पास पर्याप्त बाधा जानकारी होनी चाहिए। आप वास्तव में क्या हासिल करने की कोशिश कर रहे हैं? – jrturton

+0

मैं इशारा के साथ छवि दृश्य का आकार बदलना चाहता हूं। ऑटो लेआउट बाधाएं चुटकी इशारे को छवि दृश्य को छोटा बनाने की अनुमति नहीं देगी। – Eric

+0

बस एक स्पष्ट XIB फ़ाइल के लिए स्पष्ट होना .. ** ** ** ऑटोलायआउट (यानी "बाधाओं को दूर करने" को बंद करने के लिए) बस ShowFileInspector पर क्लिक करें, और बस "autolayout" अनचेक करें। Xib पर प्रत्येक आइटम अब "पुरानी" शैली ("चिपचिपा तीर" और इसी तरह के साथ काम करेगा।) – Fattie

उत्तर

86

मैं मानता हूँ Xcode ऑटो लेआउट अगर आप कुछ विशेष करना चाहता हूँ उपयोग करने के लिए भयानक है ...

क्या मैं प्रोग्राम के की कमी दूर करने के लिए उपयोग करें:

[detailsPhotoView removeConstraints:detailsPhotoView.constraints]; 
+0

धन्यवाद, यह काम किया। मैंने सभी बाधाओं को एक दृश्य से हटा दिया है और दृश्य प्रारूप भाषा का उपयोग करके उन्हें फिर से सेट किया है; ऊपर दिए गए कोड को स्वयं को निर्दिष्ट करने से पहले बाधाओं को दूर करने की आवश्यकता है, अन्यथा xcode शिकायत जारी रखेगा –

+0

यदि आप UIImageView से बाधा को हटाने का प्रयास कर रहे हैं तो भी एक बात याद रखें, फिर सुनिश्चित करें कि आप कोड द्वारा उस दृश्य को जोड़ते हैं। आईबीआउटलेट का उपयोग न करें क्योंकि ऐसा लगता है कि आपके सेट फ्रेम कोड पर कोई प्रभाव नहीं पड़ता है। मैं बस इस बकवास में भाग गया। –

6

आप की कमी नहीं नहीं हो सकता है - आप जगह में पर्याप्त कमी होना आवश्यक है स्पष्ट रूप से आकार और स्थिति हर दृश्य

को आप एक आकार बदलने योग्य मानना ​​है कि autolayout के टुकड़ों से बनी है बना सकते हैं।

उदाहरण के लिए, आपके मामले में, आप स्थिति की बाधाएं बना सकते हैं - कहें, छवि पर्यवेक्षण के केंद्र में क्षैतिज और लंबवत छवि दृश्य का केंद्र पिन करें।

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

चुटकी संकेतों के जवाब में, आप दो आकार की बाधाओं के .constant गुणों को समायोजित कर सकते हैं, और setNeedsLayout पर कॉल कर सकते हैं। यह आपके केंद्र को पिन करने के दौरान आपके छवि दृश्य का आकार बदल देगा।

यदि आप उपरोक्त निश्चित पहलू अनुपात सुझाव करते हैं, तो बाधाओं का उपयोग करके दृश्य का आकार बदलना वास्तव में फ्रेम को सेट करने से कहीं अधिक सरल है।

+0

मैं इस कंटेनर UIView के भीतर कुछ भी पिन नहीं करना चाहता हूं। मैं छवि दृश्य (UIView के भीतर एक) को पिनिंग, ले जाया जा सकता है, पनडुब्बी आदि को कुछ भी पिन किए बिना या किसी भी आकार की बाधाओं के बिना सक्षम होना चाहता हूं। इसके लिए मैं किस स्थिरांक निर्धारित करूंगा? मैं सभी बाधाओं को दूर करने के अपने तत्काल विचार को प्राप्त नहीं कर सकता। – Eric

+0

यदि आप इसे स्थानांतरित करने के साथ-साथ आकार बदलना चाहते हैं, तो आपको स्थिति की बाधाओं की आवश्यकता होती है, जिनके पास आपके पास आउटलेट भी हैं जिन पर आप कोड में संशोधित कर सकते हैं जैसा कि मैंने उपरोक्त आकार की बाधाओं का वर्णन किया है। आपको बाधाएं नहीं हैं - आपके पास अनजाने आकार और प्रत्येक दृश्य को स्थान देने के लिए पर्याप्त बाधाएं होनी चाहिए। – jrturton

+0

क्या आप इसे उत्तर देने के लिए एक संपादन के रूप में जोड़ देंगे: आपके पास अनजाने आकार और प्रत्येक दृश्य को स्थान देने के लिए पर्याप्त बाधाएं होनी चाहिए। तो मैं इसे स्वीकार करूंगा। – Eric

8

यहां दो अलग-अलग मुद्दे हैं:

  1. बाधाओं
  2. कैसे UIImageView आलोचना करने के लिए और/या आकार दिया जब अपने लेआउट की कमी द्वारा नियंत्रित किया जाता अनुमति देने के लिए बिना एक UIImageView सेटअप करने के लिए Xcode का उपयोग कैसे करें।

(1) के बारे में, jturton सही है। जब तक आप एक्सकोड के भीतर ऑटो लेआउट सक्षम कर चुके हैं, तब तक एक्सकोड गारंटी देगा/आवश्यकता होगी कि आपके दृश्य के आकार और स्थान को विशिष्ट रूप से निर्धारित करने के लिए पर्याप्त बाधाएं हों।

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

यदि UIImageView पर कोई बाधा नहीं थी, तो इसका लेआउट निर्धारित नहीं किया जाएगा, इसलिए आप इसे एक्सकोड में सेट नहीं कर सकते हैं। इसे ठीक करने के लिए, आपको क्या करना चाहिए, उन सभी बाधाओं को आईबीओटलेट्स सेट करने के लिए एक्सकोड का उपयोग करना है, जिन्हें आप निकालना चाहते हैं, और फिर अपने UIView के जागने में FromNib: या अपने UIViewController के दृश्य में DidLoad: आप मैन्युअल रूप से हटाए गए कॉन्फ़्रेंस को कॉल करके बाधाओं को हटा दें:।

हालांकि, अब आपके UIImageView का लेआउट कम से कम निर्धारित है। तो इस बिंदु पर आप मैन्युअल रूप से नई बाधाओं को जोड़ना चाहते हैं जो आपको UIImageView को स्थानांतरित करने और आकार बदलने की अनुमति देगी, जो हमें प्रश्न (2) पर लाता है।

के बारे में (2), कैसे & कदम एक दृश्य जिसका लेआउट की कमी से निर्धारित होता है आकार बदलने के लिए, इस सवाल का जवाब चुटकी & पैन जेस्चर का पता लगाने के लिए हमेशा की तरह सेटअप इशारा recognizers के लिए है, लेकिन उन इशारा setFrame बुला recognizers के बजाय: करने के लिए दृश्य को संशोधित करें, उन्हें NSLayoutConstraint के constant पैरामीटर को संशोधित करना चाहिए जो UIImageView के फ्रेम को निर्धारित करता है और फिर लेआउट को कॉल करता है IFNeeded :, जो लेआउट सिस्टम को तुरंत संशोधित बाधा को नए फ्रेम में अनुवाद करने का कारण बनता है।

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

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

+2

बाधाओं को हटाने के बारे में एक पिटा है: आपको उस दृश्य से एक बाधा को दूर करने की आवश्यकता है जो इसे "होस्ट" करता है। जैसे यदि आपके पास स्क्रॉल व्यू के अंदर और छवि दृश्य है और उनके बीच एक बाधा है, तो यह स्क्रॉल है जो इसे होस्ट करता है।बाधा छवि दृश्य की 'बाधाओं' संपत्ति में मौजूद नहीं होगी, 'हटाएं कॉन्स्ट्रेन:' को कॉल करने के लिए छवि दृश्य पर चुपचाप अनदेखा किया जाएगा, और मेजबान दृश्य को बाधा से प्राप्त करने का कोई तरीका नहीं है। इस प्रकार आपको स्क्रॉल व्यू और बाधा दोनों के लिए आउटलेट रखना होगा और विशेष रूप से '[self.scrollView removeConstraint: self.constraint]' कॉल करें। अरे! –

24

XCode 5 में एक विकल्प है, जबकि संपादन बाधाएं 'निर्माण समय पर निकालें'। यदि यह सक्षम है तो रन-टाइम के दौरान बाधा स्वचालित रूप से हटा दी जाएगी। इंटरफ़ेस बिल्डर को खुश रखने के लिए विकल्प है यदि आप विशेष बाधाओं को नहीं चाहते हैं।

+0

सर्वश्रेष्ठ उत्तर, संक्षिप्त और सटीक। – Borzh

+0

एक्सकोड 6 में इसे अब प्लेसहोल्डर पर सेट विकल्प के साथ आंतरिक आकार कहा जाता है। – ChrisStillwell

5

आप

[yourElement removeFromSuperview]; 

कॉल कर सकते हैं और फिर

[yourSuperview addSubview:yourElement]; 

फोन yourElement से सभी बाधाओं को दूर करने और देखने के लिए इसे वापस जोड़ने के लिए।

यह उल्लेख है कि यदि आप एक UIView श्रेणी या विस्तार की तरह कुछ पर ऊपर कर रहे हैं, तो आप superview से हटाने से पहले दृश्य के superview के लिए एक संदर्भ को बचाने की जरूरत के लायक है:

var theSuperview = self.superview 
self.removeFromSuperview() 
theSuperview?.addSubview(self) 

तुम भी आवश्यकता हो सकती है पर्यवेक्षण से हटाने के बाद कमजोर होने के बजाय अपना एलीमेंट मजबूत बनाने के लिए संभावित रूप से आप इसका संदर्भ खो सकते हैं।

+0

मेरे पास एक कस्टम ऑब्जेक्ट ऑब्जेक्ट है। अवलोकन है कि केवल निकालें कॉन्स्ट्रेनेंट विधि का पालन नहीं करेगा। यह बहुत अच्छा हल किया। जैसा कि मैंने आशा की थी, वैसे भी कोई चेतावनी और व्यवहार प्रोग्रामेटिक रूप से परिभाषित नहीं किया गया था। धन्यवाद एडम! –

4

यदि आप बस पदानुक्रम से एक दृश्य को हटाना चाहते हैं, तो बस [theView removeFromSuperview] पर कॉल करें। इसे प्रभावित करने वाली किसी भी बाधा को भी हटा दिया जाएगा।

हालांकि, कभी-कभी आप अस्थायी रूप से को हटाकर भी एक दृश्य वापस रखना चाहेंगे।

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

-(NSArray*) stealExternalConstraintsUpToView: (UIView*) superview 
{ 
    NSMutableArray *const constraints = [NSMutableArray new]; 

    UIView *searchView = self; 
    while(searchView.superview && searchView!= superview) 
    { 
     searchView = searchView.superview; 

     NSArray *const affectingConstraints = 
     [searchView.constraints filteredArrayUsingPredicate: 
     [NSPredicate predicateWithBlock:^BOOL(NSLayoutConstraint *constraint, NSDictionary *bindings) 
      { 
       return constraint.firstItem == self || constraint.secondItem == self; 
      }]]; 

     [searchView removeConstraints: affectingConstraints]; 
     [constraints addObjectsFromArray: affectingConstraints]; 
    } 

    return constraints; 
} 

विधि एक सरणी में निकाली गई कमी है कि आप कहीं रख सकते हैं, जिससे कि बाद में आप बाधाओं वापस जोड़ सकते हैं वापस लौटा देता है।

इस तरह यह थोड़ा का प्रयोग करें ...

NSArray *const removedConstraints = [viewToHide stealExternalConstraintsUpToView: self.view]; 
[viewToHide setHidden: YES]; 

और बाद में, बाधाओं वापस डाल दिया।

आईओएस 8 के रूप में आपको यह सोचने की आवश्यकता नहीं है कि बाधाओं को कहां रखा जाना चाहिए। बस आईओएस के पुराने संस्करणों के साथ इस का उपयोग करें ...

[NSLayoutConstraint activateConstraints: removedConstraints]; 
[viewToHide setHidden: NO]; 

तुम कहाँ कमी वापस जोड़ने के लिए के बारे में मुश्किल में सोचने की जरूरत नहीं है। फिर नियंत्रक के self.view में फेंको। प्रदान की गई बाधाएं उन सभी विचारों के पर्यवेक्षण में हैं जो वे प्रभावित करते हैं, वे काम करेंगे।

[self.view addConstraints: removedConstraints]; 
[viewToHide setHidden: NO]; 
+0

सक्रिय करें IOS 8 –

+0

@ b.zdybowicz के बाद से उपलब्ध है - धन्यवाद, यह स्पष्ट करने के लिए अपडेट किया गया है। कोई भी संपादन कर सकता है, वैसे - वे कभी-कभी नियंत्रित होते हैं, हालांकि। – Benjohn

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