क्या मैं रनटाइम के दौरान एक विशिष्ट सबव्यू के लिए ऑटोलेयआउट को अक्षम कर सकता हूं?


104

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

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

जवाबों:


168

मुझे भी यही समस्या थी। लेकिन मैंने इसका हल निकाल लिया है।
हां, आप एक विशेष के लिए रनटाइम पर ऑटो लेआउट को अक्षम कर सकते हैं UIView, बजाय इसे पूरे एक्सिब या स्टोरीबोर्ड के लिए अक्षम करने के लिए जो कि डिफ़ॉल्ट रूप से एक्सकोड 4.3 और बाद में सेट है।

इससे पहले कि आप अपने सबव्यू का फ्रेम सेट translatesAutoresizingMaskIntoConstraintsकरें YES, सेट करें:

self.exampleView.translatesAutoresizingMaskIntoConstraints = YES;
self.exampleView.frame = CGRectMake(20, 20, 50, 50);

2
यह बहुत अधिक विचारों वाले कुछ अधिक जटिल मामलों के लिए ओवरकिल जैसा दिखता है। इस के रूप में सरल कुछ के लिए, यह ठीक है।
esh

@MuhammadAamirALi सबव्यू को हटा दें और फिर इसे वापस जोड़ें प्रदर्शन में कमी हो सकती है। क्या हम बेहतर समाधान संग्रह कर सकते हैं?
नट दीन्ह

2
@ डिनहाट मैंने जवाब स्पष्ट किया। सबव्यू को हटाना और फिर से जोड़ना आवश्यक नहीं है।
लिएन्ड्रोस

5
यह मुझे चेतावनी देता है: "एक साथ बाधाओं को संतुष्ट करने में असमर्थ।"
NSPratik

1
आपने मेरा दिन बचाया ... TranslatesAutoresizingMaskIntoConstraints ... जो इस शेकिंग हेड की
Tintenklecks

50

मेरे पास एक ऐसा ही मुद्दा था जहां ऑटोलैयट रन टाइम में मेरे कुछ फ्रेम-सेटिंग को ओवरराइड कर रहा था (मुझे एक गतिशील दृश्य मिला कि कुछ मामलों में एक नए व्यू कंट्रोलर को धक्का दिया गया ... धक्का देना और फिर वापस दबाकर प्रारंभिक दृश्य रीसेट करना होगा)।

मैंने viewDidLayoutSubviewsअपने व्यू कंट्रोलर के साथ अपना हेरफेर कोड डालकर इसे पास कर लिया । ऐसा लगता है कि बाद में जो भी बाधा मौज कहा जाता है उसे कहा जाता है, लेकिन देखने से पहले, ताकि उपयोगकर्ता कोई समझदार न हो।


1
Self.navigationItem.titleView के लिए काम नहीं करता है। फिर भी फ्रेम परिवर्तन का सम्मान नहीं करता है।
हेनरिक एर्लैंड्सन

1
यदि आप शीर्षक दृश्य के फ्रेम के साथ मिलाने की कोशिश कर रहे हैं, तो मैं इसे कंटेनर दृश्य के अंदर रखूंगा और नेविगेशन दृश्य के कस्टम दृश्य के रूप में कंटेनर दृश्य जोड़ूंगा।
jmstone617

2
यह मेरे लिए भी काम किया। मैं 2h बर्बाद करूँगा: 22 मीटर इस वर्कअराउंड की खोज से पहले लौकिक दीवार के खिलाफ मेरे सिर को पीटना।
टीएमसी

धन्यवाद दोस्त। मैं अपने दूसरे दिन में इस मुद्दे से जूझ रहा हूं और अब यह काम करता है!
एपोस्टोलोव

28

शायद बस (उस दृश्य को प्रभावित करने वाले अतिरिक्त अवरोधों को जोड़ने और स्थापित translatesAutoresizingMaskIntoConstraintsकरने के लिए YES) आपको ऑटो लेआउट सिस्टम से लड़ने के बिना फ्रेम सेट करने देगा।


17

IOS 8 में आप सक्रिय होने या न होने के लिए NSLayoutConstraint सेट कर सकते हैं। इसलिए अगर मैं इंटरफ़ेस बिल्डर का उपयोग कर रहा हूं, तो मैं अपने सभी अवरोधों को एक आउटलेट में जोड़ता हूं और फिर उपयोग करने के लिए सक्रिय या निष्क्रिय कर देता हूं:

NSLayoutConstraint.deactivateConstraints(self.landscapeConstraintsPad)
NSLayoutConstraint.activateConstraints(self.portraitConstraintsPad)

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

या आप RemoveConstraints और addConstraints का उपयोग करके सक्रिय / निष्क्रिय कर सकते हैं।


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

वैसे आप इसे आकार वर्गों का उपयोग करके कर सकते हैं: developer.apple.com/library/ios/recipes/… , लेकिन मैं इसे इस तरह से नहीं कर सका क्योंकि मैं iOS 7 का भी समर्थन कर रहा था और आकार वर्ग iOS 7 का पूरी तरह से समर्थन नहीं करते हैं। । मैंने इसे परस्पर विरोधी बाधा की प्राथमिकता को कम करके किया। आदर्श नहीं है, लेकिन यह चेतावनी को रोकता है। मुझे लगता है कि मैंने इसे वैसे भी कैसे किया ....
bandejapaisa

9

मुझे नहीं पता कि यह किसी और की मदद करेगा, लेकिन मैंने इसे सुविधाजनक बनाने के लिए एक श्रेणी लिखी क्योंकि मुझे लगता है कि मैं खुद को ऐसा कर रहा हूं।

UIView + DisableAutolayoutTemporarily.h

#import <UIKit/UIKit.h>

@interface UIView (DisableAutolayoutTemporarily)

// the view as a parameter is a convenience so we don't have to always
// guard against strong-reference cycles
- (void)resizeWithBlock:(void (^)(UIView *view))block;

@end

UIView + DisableAutolayoutTemporarily.m

#import "UIView+DisableAutoResizeTemporarily.h"
@implementation UIView (DisableAutoResizeTemporarily)

- (void)resizeWithBlock:(void (^)(UIView * view))block
{
    UIView *superview = self.superview;
    [self removeFromSuperview];
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    __weak UIView *weakSelf = self;
    block(weakSelf);
    [superview addSubview:self];
}

@end

मैं इसे इस तरह से उपयोग करता हूं:

[cell.argumentLabel resizeWithBlock:^(UIView *view) {
    [view setFrame:frame];
}];

आशा करता हूँ की ये काम करेगा।


प्रतिभाशाली ! मैंने किसी भी UIView के लिए एक सरल "HideControl" फ़ंक्शन लिखने के लिए आपके कोड के संशोधित संस्करण का उपयोग किया। यह मूल रूप से एक UIView की ऊँचाई को 0 पर सेट करता है, लेकिन, महत्वपूर्ण रूप से, यह आपके कोड को AutoLayout को ठीक से संभालने के लिए उपयोग करता है ("someView.hidden = TRUE" का उपयोग करने के विपरीत)। इसलिए नियंत्रण जो छिपे हुए नियंत्रण के नीचे दिखाई देता था, और इसमें ऊर्ध्वाधर रिक्ति जुड़ी हुई थी, अब अंतर को भरने के लिए स्क्रीन पर शिफ्ट हो जाएगा, जहां पहले से छिपा हुआ दृश्य दिखाई दे रहा था।
माइक गल्डहिल

6

आप उस translatesAutoresizingMaskIntoConstraintsप्रकार को सेट कर सकते Booleanहैं, जो यूआईईयूआई के स्टोरी डिफाइंड रनटाइम एट्रीब्यूट्स में मान को सेट करता है जो आप xib / स्टोरीबोर्ड में चाहते हैं।


2
  • 4.5 में खुला प्रोजेक्ट
  • स्टोरीबोर्ड का चयन करें
  • फ़ाइल इंस्पेक्टर खोलें
  • इंटरफ़ेस बिल्डर दस्तावेज़ के तहत 'ऑटोलॉयआउट का उपयोग करें' को अनचेक करें

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


10
यह संपूर्ण स्टोरीबोर्ड / नीब के लिए ऑटोलैयूट को निष्क्रिय करता है। मैं जिस चीज़ की तलाश कर रहा था वह एक स्टोरीबोर्ड / नायब के भीतर विशेष रूप से साक्षात्कार के लिए एक तरीका (आदर्श रूप से प्रोग्रामेटिक) था जो स्टोरीबोर्ड / एनआईबी को निर्दिष्ट करते हुए बाकी कामों को छोड़ते हुए ऑटोलेयूट का उपयोग नहीं करता है।
भयावह

आप कई स्टोरीबोर्ड का उपयोग कर सकते हैं और आवश्यकतानुसार ऑटोलॉययट के साथ / बिना इनवॉइस का उपयोग कर सकते हैं: // यूआईटोरीबोर्ड के लिए स्टॉरबोर्ड और डिटेल व्यू कंट्रोलर को प्रारंभ करें * sb = [UIStoryboard स्टोरीबोर्डWithName: @ "स्टोरीबोर्ड" बंडल: [NSBundle mainBundle]]; डिटेलव्यूकंट्रोलर * डीवीकंट्रोलर = [एसबी इंस्टेंटव्यूकंट्रोलरथाइथाइंटिफायर: एंट्री.व्यूऑनलाइनर];
माइक Bobbitt

1

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


1

मेरे विचार में मेरे पास एक लेबल और एक पाठ था। लेबल में पैन जेस्चर था। खींचें के दौरान लेबल ठीक चलता रहता है। लेकिन जब मैं टेक्स्ट बॉक्स कीबोर्ड का उपयोग करता हूं, तो लेबल अपनी स्थिति को ऑटो लेआउट में परिभाषित मूल स्थान पर रीसेट करता है। जब मैंने लेबल के लिए स्विफ्ट में निम्नलिखित जोड़ा तो समस्या हल हो गई। मैंने इसे व्यूप्लेयर में जोड़ा है लेकिन यह बहुत ज्यादा जोड़ा जा सकता है कहीं भी आप लक्ष्य क्षेत्र तक पहुंच सकते हैं।

self.captionUILabel.translatesAutoresizingMaskIntoConstraints = true

0

यह बिना स्टोरीबोर्ड या xib फ़ाइलों के किसी प्रोजेक्ट में मेरे साथ हुआ। सभी 100% कोड। मेरे पास नीचे एक विज्ञापन बैनर था और मैं चाहता था कि दृश्य बैनर विज्ञापन बैनर पर रुक जाए। लोड करने के बाद दृश्य अपने आप आकार बदल जाएगा। मैंने इस पृष्ठ पर हर संकल्प की कोशिश की, लेकिन उनमें से किसी ने भी काम नहीं किया।

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

मैं सोच रहा हूं कि क्या आप एक ऐसा दृश्य चाहते हैं जो सामान्य आकार का नहीं है जो खिड़की को भरता है तो आपको उसके लिए एक उप दृश्य का उपयोग करना चाहिए।


0

मुझे एक समान परिदृश्य का सामना करना पड़ा है, जहां मैं एक परियोजना में शामिल हुआ था जिसे ऑटो-लेआउट के साथ शुरू किया गया था, लेकिन मुझे कई दृश्यों के लिए गतिशील समायोजन करने की आवश्यकता थी। यहाँ मेरे लिए काम किया है:

  1. इंटरफ़ेस बिल्डर में दिए गए दृश्य या घटक नहीं हैं।

  2. अपने विचारों को विशुद्ध रूप से प्रोग्राम में जोड़ें / आवंटन के साथ शुरू करें और उनके फ्रेम को उचित रूप से सेट करें।

  3. किया हुआ।


0

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

उदाहरण के लिए, यदि आपके पास दो दृश्य (myView और अन्य दृश्य) के बीच 0 का एक लंबवत अवरोध है, और आपके पास एक पैन जेस्चर या कुछ ऐसा है जो myView की ऊंचाई को समायोजित करता है, तो आप समायोजित मूल्यों के साथ बाधा को पुनर्गणना कर सकते हैं।

self.verticalConstraint.constant = newMyViewYOriginValue - (self.otherView.frame.origin.y + self.otherView.frame.size.height);
[self.myView needsUpdateConstraints];

0

आप में से जो ऑटो लेआउट का उपयोग कर रहे हैं, कृपया मेरे समाधान की जाँच करें । आपको उन @IBOutletबाधाओं को बनाना चाहिए जो आप समायोजित करना चाहते हैं और फिर उनके स्थिरांक को बदल सकते हैं।


-16

अगर यह xib फ़ाइल है:

  1. .xib फ़ाइल चुनें
  2. "फ़ाइल का स्वामी" चुनें
  3. उपयोगिताएँ दिखाएं
  4. "फाइल इंस्पेक्टर" पर क्लिक करें
  5. "इंटरफ़ेस बिल्डर दस्तावेज़" के तहत अक्षम करें: "ऑटोलॉयआउट का उपयोग करें"

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