जब कोई दृश्य छिपा हो, तो अन्य विचारों को स्थानांतरित करने के लिए ऑटो-लेआउट का उपयोग कैसे करें?


333

मैंने आईबी में अपने कस्टम सेल को डिज़ाइन किया है, इसे उप-वर्गित किया है और अपने आउटलेट्स को अपने कस्टम वर्ग से जोड़ा है। सेल सामग्री में मेरे तीन साक्षात्कार हैं जो हैं: UIView (cdView) और दो लेबल (titleLabel और emailLabel)। प्रत्येक पंक्ति के लिए उपलब्ध डेटा के आधार पर, कभी-कभी मैं अपने सेल में UIView और दो लेबल प्रदर्शित करना चाहता हूं और कभी-कभी केवल दो लेबल। मैं जो करने की कोशिश कर रहा हूं, वह उस तरह से बाधाओं को सेट करने के लिए है, अगर मैं छिपाकर यूआईईवीवाई संपत्ति सेट करता हूं या मैं इसे पर्यवेक्षण से हटा दूंगा कि दोनों लेबल बाईं ओर चले जाएंगे। मैंने 10x के लिए UIView अग्रणी बाधा को Superview (सेल सामग्री) और UILABels अग्रणी बाधाओं को 10 px के अगले दृश्य (UIVIV) के लिए सेट करने का प्रयास किया। बाद में मेरे कोड में

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
...
Record *record = [self.records objectAtIndex:indexPath.row];

if ([record.imageURL is equalToString:@""]) {
     cell.cdView.hidden = YES;
}

मैं अपने cell.cdView को छिपा रहा हूं और मैं चाहूंगा कि लेबल बाईं ओर जाएं लेकिन वे सेल में उसी स्थिति में रह रहे हैं। मैंने पर्यवेक्षण से cell.cdView को हटाने की कोशिश की, लेकिन यह भी काम नहीं किया। मैंने जो कुछ भी है उसे स्पष्ट करने के लिए छवि संलग्न की है।

सेल

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

.....

परिवर्तन की कमी मान रनटाइम - इस उत्तर की
कंपाई

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

जवाबों:


373

यह संभव है, लेकिन आपको थोड़ा अतिरिक्त काम करना होगा। पहले रास्ते से हटने के लिए कुछ वैचारिक बातें हैं:

  • छिपे हुए दृश्य, भले ही वे आकर्षित न करें, फिर भी ऑटो लेआउट में भाग लेते हैं और आमतौर पर अपने फ्रेम को बनाए रखते हैं , जिससे उनके स्थानों में अन्य संबंधित विचार दिखाई देते हैं।
  • अपने पर्यवेक्षक से एक दृश्य को हटाते समय, सभी संबंधित बाधाओं को उस दृश्य पदानुक्रम से भी हटा दिया जाता है।

आपके मामले में, इस संभावना का अर्थ है:

  • यदि आप अपना बायाँ दृश्य छुपाने के लिए सेट करते हैं, तो लेबल यथावत बने रहते हैं, क्योंकि वह बायाँ दृश्य अभी भी जगह ले रहा है (भले ही यह दृश्य नहीं है)।
  • यदि आप अपना बायाँ दृश्य हटाते हैं, तो आपके लेबल संभवतः अस्पष्ट रूप से बचे रहेंगे, क्योंकि आपके पास अब अपने लेबल के बाएँ किनारों के लिए कोई बाधा नहीं है।

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

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

एक महत्वपूर्ण चेतावनी: यदि आप कभी भी अपने बाएं दृश्य को चित्र में वापस लाना चाहते हैं, तो न केवल आपको इसे दृश्य पदानुक्रम में जोड़ना होगा, बल्कि आपको एक ही समय में इसके सभी अवरोधों को फिर से स्थापित करना होगा। इसका मतलब है कि जब भी उस दृश्य को दोबारा दिखाया जाता है, तो आपको अपने 10p रिक्ति अवरोध को दृश्य और उसके लेबल के बीच वापस रखने का एक तरीका चाहिए।


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

मेरी राय में, यह रास्ता नहीं है। इसके बजाय आपको उस दृश्य के लिए चौड़ाई / ऊँचाई-अवरोध का उपयोग करना चाहिए जिसे आप छिपाना चाहते हैं।
०१

26
मैं आदरपूर्वक असहमत हूं। यदि आप (उदाहरण के लिए) दृश्य की चौड़ाई 0 पर सेट करते हैं, तो आप दो समस्याओं में भाग लेंगे। सबसे पहले, अब आपके पास सुपरवाइवे और दृश्यमान दृश्य के बीच डबल रिक्ति है: |-(space)-[hidden(0)]-(space)-[visible]प्रभावी रूप से |-(2*space)-[visible]। दूसरा, वह दृश्य अपने स्वयं के दृश्य उपशीर्षक और बाधाओं के आधार पर बाधा उल्लंघन फेंकना शुरू कर सकता है - आप गारंटी नहीं दे सकते कि आप मनमाने ढंग से 0 चौड़ाई पर एक दृश्य को बाधित कर सकते हैं और इसे काम कर सकते हैं।
टिम

1
यदि आप आंतरिक सामग्री आकार के साथ एक दृश्य का उपयोग कर रहे हैं तो टिम का उत्तर जाने का अनूठा तरीका लगता है।
बालकोथ

धन्यवाद टिम। मैं बाधा असंगतताओं से बचने के लिए एक उच्च प्राथमिकता के साथ 0 का एक बाधा निर्धारित करता हूं, लेकिन अब मुझे लगता है कि दोहरी जगह के साथ समस्या है। मुझे वह समस्या नहीं थी क्योंकि मैं कभी भी दो विचारों को एक साथ नहीं दिखाता (मेरा मामला:) |-[otherViews]-[eitherThis][orThis]-|, लेकिन मैं अंततः उस समस्या में चला जाता।
फेरन मायलिनच

207

रनटाइम के दौरान बाधाओं को जोड़ना या निकालना एक भारी ऑपरेशन है जो प्रदर्शन को प्रभावित कर सकता है। हालांकि, एक सरल विकल्प है।

जिस दृश्य को आप छिपाना चाहते हैं, उसके लिए एक चौड़ाई की बाधा निर्धारित करें। उस दृश्य के लिए एक प्रमुख क्षैतिज अंतराल के साथ अन्य विचारों को विवश करें।

छिपाने के लिए, .constantचौड़ाई की चौड़ाई को 0.f में अद्यतन करें । अन्य विचार स्वचालित रूप से स्थिति संभालने के लिए बाएँ चले जाएँगे।

अधिक जानकारी के लिए मेरा अन्य उत्तर यहां देखें:

रनटाइम के दौरान लेबल की बाधाओं को कैसे बदलें?


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

2
@ skinsfan00atg यदि आप आंतरिक सामग्री आकार के साथ एक दृश्य का उपयोग कर रहे हैं, तो आप इस समाधान का उपयोग नहीं कर सकते।
बालकोथ

@ बाल्कोथ क्यों नहीं? आप केवल सामग्री को प्राथमिकता देने को कम कर सकते हैं
अधिकतम मैकलेड

2
@MaxMacLeod यदि आप कंटेंट हगिंग प्राथमिकता को कम करते हैं तो आप आंतरिक सामग्री आकार का उपयोग नहीं कर रहे हैं, आप बाधा द्वारा इंगित आकार का उपयोग कर रहे हैं।
बालकोथ

2
@MaxMacLeod ठीक है, मुझे तुम्हारा क्या मतलब है। जब आप दृश्य को छुपाना चाहते हैं, और जब आप फिर से उस मूल्य को फिर से दिखाना चाहते हैं, तो आपको कोड में संपीड़न प्रतिरोध प्राथमिकता को 0 (सामग्री हगिंग नहीं) सेट करने की आवश्यकता है। इसके अलावा आपको दृश्य के आकार को सेट करने के लिए इंटरफ़ेस बिल्डर में एक बाधा जोड़ने की आवश्यकता है। कोड में इस गर्भनिरोधक को छूने की आवश्यकता नहीं है।
बालकोथ

87

जो लोग केवल iOS 8+ का समर्थन करते हैं , उनके लिए एक नया बूलियन प्रॉपर्टी सक्रिय है । यह गतिशील रूप से केवल आवश्यक बाधाओं को सक्षम करने में मदद करेगा

PS बाधा आउटलेट मजबूत होना चाहिए , कमजोर नहीं

उदाहरण:

@IBOutlet weak var optionalView: UIView!
@IBOutlet var viewIsVisibleConstraint: NSLayoutConstraint!
@IBOutlet var viewIsHiddenConstraint: NSLayoutConstraint!

func showView() {
    optionalView.isHidden = false
    viewIsVisibleConstraint.isActive = true
    viewIsHiddenConstraint.isActive = false
}

func hideView() {
    optionalView.isHidden = true
    viewIsVisibleConstraint.isActive = false
    viewIsHiddenConstraint.isActive = true
}

स्टोरीबोर्ड में एक त्रुटि को ठीक करने के लिए आपको Installedइन बाधाओं में से एक के लिए चेकबॉक्स को अनचेक करना होगा ।

UIStackView (iOS 9+)
एक और विकल्प आपके विचारों को अंदर लपेटना है UIStackView। एक बार दृश्य छिप जाने के बाद UIStackViewलेआउट स्वचालित रूप से अपडेट हो जाएगा


सक्रिय रूप से काम करता है। लेकिन अगर मैं इसे एक पुन: प्रयोज्य सेल के अंदर उपयोग करता हूं, तो सक्रिय से निष्क्रिय करने के लिए, काम करता है, लेकिन सक्रिय करने के लिए निष्क्रिय करने के लिए नहीं। कोई विचार? या आप शायद एक उदाहरण प्रदान कर सकते हैं?
ली

10
ऐसा इसलिए होता है क्योंकि डिएक्टेड कांस्ट्रेन्ड लोडेड या डीललॉक्ड नहीं होता है। आपका बाधा आउटलेट मजबूत होना चाहिए, कमजोर नहीं
सिल्मारिल

हम उस "सक्रिय" संपत्ति को कहां से पा सकते हैं?
लक्ष्मी रेड्डी


ऐसा लगता है कि अति-बाधा + सेट बाधा गतिविधि सबसे उचित जवाब हो सकता है।
तिंग यी शिह

68

UIStackViewजब hiddenसंपत्ति अपने किसी भी साक्षात्कार (iOS 9+) में बदल जाती है, तो अपने विचारों को स्वचालित रूप से बदल देता है।

UIView.animateWithDuration(1.0) { () -> Void in
   self.mySubview.hidden = !self.mySubview.hidden
}

WWDC के इस वीडियो में डेमो के लिए 11:48 पर जाएं:

ऑटो लेआउट के रहस्य, भाग 1


मैं एक नेस्टेड स्टैक दृश्य को छिपा दिया और पूरे स्टैक दृश्य गायब हो गया।
इयान वार्बर्टन

5
यह स्वीकृत उत्तर होना चाहिए। इंटरफ़ेस बिल्डर डिजाइन पर wwdc 2015 की सेब की सिफारिशों के बाद।
थिबुत नोआ

@thibautnoah और फिर iOS 8- के बारे में क्या कहना है?
बैगेज

5
@बैगेज जब तक आप फेसबुक या गूगल नहीं हैं तब तक आप इसे छोड़ सकते हैं। Beyong iOS 9 कवरेज के साथ आप 90% से अधिक उपकरणों का समर्थन करेंगे, पर्याप्त से अधिक। नीचे दिए गए समर्थन के लिए अपने विकास की प्रक्रिया अपंग और आप imo नवीनतम सुविधाओं का उपयोग करने से रोका जाएगा
Thibaut नूह

16

मेरी परियोजना एक कस्टम @IBDesignableउपवर्ग का उपयोग करती है UILabel(रंग, फ़ॉन्ट, इनसेट आदि में स्थिरता सुनिश्चित करने के लिए) और मैंने कुछ इस तरह से लागू किया है:

override func intrinsicContentSize() -> CGSize {
    if hidden {
        return CGSizeZero
    } else {
        return super.intrinsicContentSize()
    }
}

यह लेबल उपवर्ग को ऑटो लेआउट में भाग लेने की अनुमति देता है, लेकिन छिपाए जाने पर कोई स्थान नहीं लेता है।


13

गोगलर्स के लिए: मैक्स के उत्तर पर निर्माण, पैडिंग मुद्दे को हल करने के लिए जो कि मैंने देखा है कि मैंने केवल लेबल की ऊंचाई बढ़ाई है और वास्तविक ऊंचाई के बजाय विभाजक के रूप में उस ऊंचाई का उपयोग किया है। इस विचार को किसी भी परिदृश्य के लिए विस्तृत किया जा सकता है जिसमें दृश्य शामिल हैं।

यहाँ एक सरल उदाहरण दिया गया है:

आईबी स्क्रीनशॉट

इस मामले में, मैं लेखक लेबल की ऊँचाई को एक उपयुक्त नक्शे पर रखता हूँ IBOutlet:

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

और जब मैंने बाधा की ऊंचाई निर्धारित की 0.0f, तो हम "पैडिंग" को संरक्षित करते हैं, क्योंकि प्ले बटन की ऊंचाई इसके लिए अनुमति देती है।


जो लोग NSLayoutConstraintमेरे लिए नए हैं, उनका मानना ​​है कि आप अपनी constantसंपत्ति को अद्यतन करना चाहते हैंauthorLabelHeight
काइल

8

IBOutlet के रूप में uiview और लेबल के बीच बाधा कनेक्ट करें और छिपे हुए = YES सेट होने पर प्राथमिकता मान को कम मान पर सेट करें


3
एक बार स्थापित होने के बाद आप एक NSLayoutConstraint की प्राथमिकता को समायोजित नहीं कर सकते; आपको एक नई बाधा को अलग प्राथमिकता के साथ निकालना और पढ़ना होगा।
टिम

7
मैंने इस विधि को काम करने के लिए प्राप्त किया है। मेरे पास एक ऐसा मामला है जो एक लेबल और एक बटन का उपयोग करता है, जहां मुझे बटन छिपाने की आवश्यकता होती है और लेबल का विस्तार होता है। मेरे पास दो बाधाएं हैं, एक शुरुआत में प्राथमिकता 751 के साथ और दूसरी 750 के साथ। तब जब मैं बटन छिपाता हूं, मैं प्राथमिकताओं को फ्लिप करता हूं, और लेबल की लंबाई बढ़ती है। यह ध्यान दिया जाना चाहिए कि यदि आप उच्च प्राथमिकता 1000 बनाने की कोशिश करते हैं, तो आपको एक त्रुटि मिलती है "एक स्थापित बाधा पर (या इसके विपरीत) से प्राथमिकता को म्यूट करना समर्थित नहीं है।" तो ऐसा नहीं है और आप ठीक लग रहे हैं। Xcode 5.1 / viewDidLoad।
जॉन बुशनेल

8

मैं क्या कर रहा था 2 xibs बना रहा था। एक बाएं दृश्य के साथ और एक इसके बिना। मैंने कंट्रोलर में दोनों को पंजीकृत किया और फिर तय किया कि सेलफोररॉइट इंडेक्सएक्सपैथ के दौरान किसका उपयोग किया जाए।

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

सामान्य तौर पर, यह संभवतः एक बेहतर समाधान है क्योंकि वे तकनीकी रूप से अलग-अलग लेआउट हैं और इसलिए अलग-अलग xibs होने चाहिए।

[self.table registerNib:[UINib nibWithNibName:@"TrackCell" bundle:nil] forCellReuseIdentifier:@"TrackCell"];
[self.table registerNib:[UINib nibWithNibName:@"TrackCellNoImage" bundle:nil] forCellReuseIdentifier:@"TrackCellNoImage"];

TrackCell *cell = [tableView dequeueReusableCellWithIdentifier:(appDelegate.showImages ? @"TrackCell" : @"TrackCellNoImage") forIndexPath:indexPath];

7

इस मामले में, मैं लेखक लेबल की ऊंचाई को एक उपयुक्त IBOutlet में मैप करता हूं:

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

और जब मैंने बाधा की ऊंचाई 0.0f निर्धारित की, तो हम "पैडिंग" को संरक्षित करते हैं, क्योंकि प्ले बटन की ऊंचाई इसके लिए अनुमति देती है।

cell.authorLabelHeight.constant = 0;

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें


6

दो UIStackView क्षैतिज और लंबवत का उपयोग करें, जब स्टैक में कुछ सबव्यू दृश्य छिपा हुआ है तो अन्य स्टैक उपविभाजक ले जाया जाएगा, वितरण का उपयोग करें -> दो UILabels के साथ ऊर्ध्वाधर स्टैक के लिए पूरी तरह से भरें और पहले UIVIV के लिए चौड़ाई और ऊंचाई की आवश्यकता निर्धारित करेंयहां छवि विवरण दर्ज करें


2

यह कोशिश करो, मैंने कोड के नीचे लागू किया है,

मेरे पास ViewController पर एक दृश्य है जिसमें अन्य तीन दृश्य जोड़े गए हैं, जब कोई दृश्य छिपा हुआ है तो दो अन्य दृश्य चलेंगे, नीचे दिए गए चरणों का पालन करें। ,

1. देखेंController.h फ़ाइल

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *viewOne;
@property (strong, nonatomic) IBOutlet UIView *viewTwo;
@property (strong, nonatomic) IBOutlet UIView *viewThree;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewOneWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewTwoWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewThreeWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewBottomWidth;
@end

2.ViewController.m

 #import "ViewController.h"
 @interface ViewController ()
{
  CGFloat viewOneWidthConstant;
  CGFloat viewTwoWidthConstant;
  CGFloat viewThreeWidthConstant;
  CGFloat viewBottomWidthConstant;
}
@end

@implementation ViewController
@synthesize viewOne, viewTwo, viewThree;

- (void)viewDidLoad {
  [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a 
  nib.

  /*
   0  0   0
   0  0   1
   0  1   0
   0  1   1
   1  0   0
   1  0   1
   1  1   0
   1  1   1
   */

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:YES];


  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

 //    [viewOne setHidden:YES];
 //    [viewTwo setHidden:YES];
 //    [viewThree setHidden:NO];

//    [viewOne setHidden:YES];
//    [viewTwo setHidden:YES];
//    [viewThree setHidden:YES];

 [self hideShowBottomBar];
  }

- (void)hideShowBottomBar
{
  BOOL isOne = !viewOne.isHidden;
  BOOL isTwo = !viewTwo.isHidden;
  BOOL isThree = !viewThree.isHidden;

  viewOneWidthConstant = _viewOneWidth.constant;
  viewTwoWidthConstant = _viewTwoWidth.constant;
  viewThreeWidthConstant = _viewThreeWidth.constant;
  viewBottomWidthConstant = _viewBottomWidth.constant;

   if (isOne && isTwo && isThree) {
    // 0    0   0
    _viewOneWidth.constant = viewBottomWidthConstant / 3;
    _viewTwoWidth.constant = viewBottomWidthConstant / 3;
    _viewThreeWidth.constant = viewBottomWidthConstant / 3;
    }
    else if (isOne && isTwo && !isThree) {
     // 0    0   1
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = 0;
    }
   else if (isOne && !isTwo && isThree) {
    // 0    1   0
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
    }
    else if (isOne && !isTwo && !isThree) {
    // 0    1   1
    _viewOneWidth.constant = viewBottomWidthConstant;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && isTwo && isThree) {
    // 1    0   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
   }
   else if (!isOne && isTwo && !isThree) {
    // 1    0   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && !isTwo && isThree) {
    // 1    1   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant;
   }
   else if (isOne && isTwo && isThree) {
    // 1    1   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
  }

 - (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
 }
 @end

यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें यहां छवि विवरण दर्ज करें

आशा है कि इस तर्क से कुछ लोगों को मदद मिलेगी।


1

मेरे मामले में मैं की लगातार सेट ऊंचाई बाधा को 0.0fऔर भी सेट hiddenकरने के लिए संपत्ति YES

दृश्य (साक्षात्कार के साथ) फिर से दिखाने के लिए मैंने इसके विपरीत किया: मैंने ऊँचाई को गैर-शून्य मान पर सेट किया और hiddenसंपत्ति को सेट किया NO


1

मैं क्षैतिज स्टैकव्यू का उपयोग करूंगा। यह उपविषय के छिपे होने पर फ्रेम को हटा सकता है।

नीचे दी गई छवि में, लाल दृश्य आपकी सामग्री के लिए वास्तविक कंटेनर है और इसमें नारंगी सुपरवाइवे (ShowHideView) के लिए 10pt अनुगामी स्थान है, तो बस ShowHideView को IBOutlet से कनेक्ट करें और इसे प्रोग्रामेटिक रूप से दिखाएं / छुपाएं / निकालें।

  1. यह तब है जब दृश्य दिखाई / स्थापित है।

दृश्य दिखाई देता है

  1. यह तब है जब दृश्य छिपा हुआ है / स्थापित नहीं है।

दृश्य छिपा / हटाया गया है


1

प्राथमिकता बाधा का उपयोग करते हुए यह मेरा एक और समाधान है। विचार 0 की चौड़ाई सेट है।

  1. कंटेनर दृश्य (नारंगी) और सेट चौड़ाई बनाएँ। यहां छवि विवरण दर्ज करें

  2. कंटेंट व्यू (लाल) बनाएं और सुपरवाइ (नारंगी) के लिए ट्रेलिंग स्पेस 10pt सेट करें। अंतरिक्ष की कमी के कारण नोटिस, अलग प्राथमिकता के साथ 2 अनुगामी बाधाएं हैं। निम्न (= 10) और उच्च (<= 10)। अस्पष्टता से बचने के लिए यह महत्वपूर्ण है। यहां छवि विवरण दर्ज करें

  3. दृश्य को छिपाने के लिए नारंगी दृश्य की चौड़ाई 0 पर सेट करें। यहां छवि विवरण दर्ज करें


0

जैसा कि no_scene ने सुझाव दिया है, आप निश्चित रूप से रनटाइम पर बाधा की प्राथमिकता को बदलकर ऐसा कर सकते हैं। यह मेरे लिए बहुत आसान था क्योंकि मेरे पास एक से अधिक अवरोधक दृश्य थे जिन्हें हटाना होगा।

यहाँ ReactiveCocoa का उपयोग करके एक स्निपेट दिया गया है:

RACSignal* isViewOneHiddenSignal = RACObserve(self.viewModel, isViewOneHidden);
RACSignal* isViewTwoHiddenSignal = RACObserve(self.viewModel, isViewTwoHidden);
RACSignal* isViewThreeHiddenSignal = RACObserve(self.viewModel, isViewThreeHidden);
RAC(self.viewOne, hidden) = isViewOneHiddenSignal;
RAC(self.viewTwo, hidden) = isViewTwoHiddenSignal;
RAC(self.viewThree, hidden) = isViewThreeHiddenSignal;

RAC(self.viewFourBottomConstraint, priority) = [[[[RACSignal
    combineLatest:@[isViewOneHiddenSignal,
                    isViewTwoHiddenSignal,
                    isViewThreeHiddenSignal]]
    and]
    distinctUntilChanged]
    map:^id(NSNumber* allAreHidden) {
        return [allAreHidden boolValue] ? @(780) : @(UILayoutPriorityDefaultHigh);
    }];

RACSignal* updateFramesSignal = [RACObserve(self.viewFourBottomConstraint, priority) distinctUntilChanged];
[updateFramesSignal
    subscribeNext:^(id x) {
        @strongify(self);
        [self.view setNeedsUpdateConstraints];
        [UIView animateWithDuration:0.3 animations:^{
            [self.view layoutIfNeeded];
        }];
    }];

0

यदि यह किसी की मदद करता है, तो मैंने दृश्य प्रारूप बाधाओं का उपयोग करने के लिए एक सहायक वर्ग बनाया । मैं अपने वर्तमान ऐप में इसका उपयोग कर रहा हूं।

AutolayoutHelper

यह मेरी जरूरतों के अनुरूप हो सकता है, लेकिन आपको यह उपयोगी लग सकता है या आप इसे संशोधित कर अपना सहायक बनाना चाहते हैं।

मुझे टिम को ऊपर दिए गए उनके उत्तर के लिए धन्यवाद देना होगा , यह उत्तर UIScrollView और इस ट्यूटोरियल के बारे में है


0

यहां बताया गया है कि मैं आपका समाधान प्राप्त करने के लिए अपने uiviews को फिर से कैसे संरेखित करूंगा:

  1. एक UIImageView ड्रॉप को खींचें और इसे बाईं ओर रखें।
  2. एक UIView को खींचें और UIImageView के दाईं ओर रखें।
  3. ड्रैग ड्रॉप दो यूआईलैबल्स को उस यूआईवाईयूवाई के अंदर ले जाना है जिसके प्रमुख और पीछे की सीमाएं शून्य हैं।
  4. UIImagView के बजाय पर्यवेक्षण के लिए 2 लेबल वाले UIView के प्रमुख अवरोध सेट करें।
  5. यदि UIImageView छिपा हुआ है, तो पर्यवेक्षण के लिए 10 px के लिए अग्रणी बाधा निर्धारित करें। ईएलएसई, 10 px + UIImageView. उपलब्धता + 10 px के लिए अग्रणी बाधा निर्धारित करें।

मैंने खुद का अंगूठा नियम बनाया। जब भी आपको किसी ऐसे uiview को छुपाना / दिखाना होता है जिसकी अड़चनें प्रभावित हो सकती हैं, तो एक uiview के अंदर सभी प्रभावित / आश्रित उपविभागों को जोड़ें और इसके अग्रणी / अनुगामी / शीर्ष / नीचे की कसौटी को लगातार क्रमिक रूप से अद्यतन करें।


0

यह एक पुराना सवाल है लेकिन फिर भी मुझे उम्मीद है कि यह मदद करेगा। एंड्रॉइड से आ रहा है, इस प्लेटफ़ॉर्म में आपके पास isVisibleइसे देखने के लिए छिपाने के लिए एक आसान तरीका है, लेकिन ऑटोलॉयट व्यू को ड्रा करने पर विचार किया गया फ्रेम भी नहीं है।

एक्सटेंशन और "एक्सटेंशन" का उपयोग करके आप आइओएस में एक समान कार्य कर सकते हैं (यह सुनिश्चित नहीं है कि यह पहले से ही UIKit में क्यों नहीं है) यहां स्विफ्ट 3 में एक कार्यान्वयन है:

    func isVisible(_ isVisible: Bool) {
        self.isHidden = !isVisible
        self.translatesAutoresizingMaskIntoConstraints = isVisible
        if isVisible { //if visible we remove the hight constraint 
            if let constraint = (self.constraints.filter{$0.firstAttribute == .height}.first){
                self.removeConstraint(constraint)
            }
        } else { //if not visible we add a constraint to force the view to have a hight set to 0
            let height = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal , toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 0)
            self.addConstraint(height)
        }
        self.layoutIfNeeded()
    }

0

इसका उचित तरीका यह है कि बाधाओं को निष्क्रिय = गलत के साथ अक्षम किया जाए। हालांकि ध्यान दें कि एक बाधा को निष्क्रिय करना इसे हटाता है और जारी करता है, इसलिए आपको उनके लिए मजबूत आउटलेट्स बनाने होंगे।


0

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


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.