iOS: कैसे एक नए ऑटोलॉययट बाधा (ऊंचाई) को चेतन करता है


123

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

पहली चुनौती:

मुझे MKMapView का आकार बदलने की आवश्यकता है और मैं इसे नए स्थान पर चेतन करना चाहूंगा। अगर मैं इस तरह से कर रहा हूँ:

[UIView animateWithDuration:1.2f
     animations:^{
         CGRect theFrame = worldView.frame;
         CGRect newFrame = CGRectMake(theFrame.origin.x, theFrame.origin.y, theFrame.size.width, theFrame.size.height - 170);
         worldView.frame = newFrame;
}];

... तब MKMapView अपनी मूल ऊँचाई पर वापस 'स्नैप' करेगा जब भी एक साहसी दृश्य अपडेट हो जाता है (मेरे मामले में एक UISegmentedControl का शीर्षक अपडेट किया जा रहा है [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0])।

इसलिए, जो मुझे लगता है कि मैं करना चाहता हूं, एमकेपॉपर व्यू की बाधाओं को माता-पिता के दृष्टिकोण के बराबर होने से बदलकर UISegmentedControl के शीर्ष के सापेक्ष किया जा रहा है जो इसे कवर कर रहा था :V:[MKMapView]-(16)-[UISegmentedControl]

मैं जो चाहता हूं वह MKMapView ऊंचाई को छोटा करने के लिए है ताकि मानचित्र दृश्य के नीचे कुछ नियंत्रण सामने आए। ऐसा करने के लिए मुझे लगता है कि मुझे एक निश्चित पूर्ण आकार के दृश्य से बाधा को बदलने की जरूरत है, जहां नीचे एक UISegmentedControl के शीर्ष पर विवश है ... और मुझे यह पसंद आएगा क्योंकि दृश्य नए आकार में सिकुड़ जाता है।

इस बारे में कोई कैसे जाता है?

संपादित करें - यह एनीमेशन हालांकि एनिमेट नहीं कर रहा है, हालांकि नीचे का दृश्य 170 को तुरंत ऊपर ले जाता है:

    [UIView animateWithDuration:1.2f
         animations:^{
             self.nibMapViewConstraint.constant = -170;

    }];

और nibMapViewConstraintआईबी में नीचे की ओर वर्टिकल स्पेस की कमी को दूर किया जाता है।


1
मुझे पता है कि आप आसानी से [UIView animateWithDuration ..] ब्लॉक में ऊंचाई परिवर्तन को चेतन करने के लिए बाधा के निरंतर मूल्य को बदल सकते हैं। आपको उस बाधा के लिए एक IBOutlet बनाने और इसे अपने xib में हुक करने की आवश्यकता है, या अन्यथा इसका संदर्भ रखें यदि आपने इसे कोड में बनाया है (या इसे देखने के लिए सभी बाधाओं के माध्यम से लूप)। निश्चित नहीं है कि संबंधित परिवर्तन कैसे करें, लेकिन मैंने पढ़ा है कि आपको केवल स्थिरांक बदलना चाहिए न कि अन्य अवरोधों के मूल्यों (अन्य मूल्यों के लिए, एक नया अवरोध पैदा करें)।
युफ

हम्म। मैंने सोचा कि मैं कर सकता हूँ, लेकिन मैं इसे एनिमेट नहीं कर रहा हूँ। यह सफलतापूर्वक बदल जाता है, और एनीमेशन ब्लॉक में है, लेकिन एनिमेशन नहीं कर रहा है!
मेल्टैमी

मेरा जवाब यहाँ मिला: < stackoverflow.com/questions/12926566/… >
Meltemi

1
मत भूलना [देखें लेआउट IfNeeded], यही मेरी समस्या थी। यह वही सवाल है जिसने मेरी समस्या को हल किया है।
युफ

जवाबों:


179

अपनी बाधा को अद्यतन करने के बाद:

[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}];

self.viewयुक्त दृश्य के संदर्भ के साथ बदलें ।


4
यह देखने के लिए स्वयं काम करता है, हालांकि जिन विचारों में उस दृश्य के लिए बाधाएं हैं वे बस तुरंत चलते हैं। मैं क्या करूं? ty
डाइटबाकॉन

7
यदि आपको उन विचारों पर भी आवश्यकता हो तो आपको लेआउट की आवश्यकता है। हालांकि यह वास्तव में ठीक से काम नहीं करता है क्योंकि यह दृश्य को ताज़ा करने के साथ ही चेतन करेगा। आप अन्य दृष्टिकोणों में केवल बाधा समायोजन को कैसे चेतन करते हैं?
ngb

3
सावधान: यदि का उपयोग कर UIViewAnimationOptionBeginFromCurrentStateलेआउट की कमी का गठन किया जाएगा इससे पहले कि एनीमेशन!
रॉबर्ट

12
layoutIfNeededउन विचारों में से प्रत्येक के लिए कॉल करने के बजाय , बस कॉल करें[[self.view superview] layoutIfNeeded];
फ्लाइंग_नाना

2
@ngb आपको एनीमेशन ब्लॉक के अंदर स्थिरांक को बदलने की आवश्यकता है । इस तरह से एनीमेशन के साथ बाधा बदल जाती है और आप उपयोग कर सकते हैं UIViewAnimationOptionBeginFromCurrentState
एरन गोल्डिन

86

यह मेरे लिए (iOS7 और iOS8 + दोनों) काम करता है। उस ऑटो लेआउट बाधा पर क्लिक करें जिसे आप समायोजित करना चाहते हैं (इंटरफ़ेस बिल्डर जैसे शीर्ष बाधा)। आगे इसे एक IBOutlet बनाते हैं;

@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;

ऊपर की ओर चेतन;

    self.topConstraint.constant = -100;    
    [self.viewToAnimate setNeedsUpdateConstraints]; 
    [UIView animateWithDuration:1.5 animations:^{
        [self.viewToAnimate layoutIfNeeded]; 
    }];

मूल स्थान पर वापस जाएं

    self.topConstraint.constant = 0;    
    [self.viewToAnimate setNeedsUpdateConstraints];  
    [UIView animateWithDuration:1.5 animations:^{
        [self.viewToAnimate layoutIfNeeded];
    }];

2
वाह!! यह वास्तव में काम करता है! यह जवाब मेरे लिए आंखें खोलने वाला था। बहुत बहुत धन्यवाद! - एरिक
एरिक वैन डेर नीट

2
@ ErikvanderNeut यह मेरे लिए भी था, खुशी है कि यह मददगार था। Im फ्रेम स्थिति के बजाय अब से बाधाओं को एनिमेट करने वाला है।
DevC

जोड़ने के लिए याद नहीं है: [containerView layoutIfNeeded]; यह सुनिश्चित करता है कि सभी लंबित लेआउट परिचालनों को पहले से तय किया गया हो।
28iii '' '

11

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


3

मैंने यह छोटा डेमो उपलब्ध कराया है । यह दिखाता है कि ऑटो-लेआउट बाधाओं को कैसे बदला जा सकता है और बहुत ही सरल उदाहरण में एनिमेटेड किया जा सकता है। बस DemoViewController.m पर एक नज़र रखना


1

अधिकांश लोग अपने विचारों पर लेआउट आइटमों के लिए ऑटोलैयूट का उपयोग करते हैं और एनिमेशन बनाने के लिए लेआउट बाधाओं को संशोधित करते हैं।

बहुत सारे कोड के बिना ऐसा करने का एक आसान तरीका है कि आप स्टोरीबोर्ड में चेतन करना चाहते हैं और फिर एक यूआईईयूईवाई बना रहे हैं जहां आप चाहते हैं कि यूआईईवाईई समाप्त हो जाए। आप यह सुनिश्चित करने के लिए कि क्या आप उन्हें चाहते हैं, दोनों UIViews बनाने के लिए आप xcode में पूर्वावलोकन का उपयोग कर सकते हैं। उसके बाद, समाप्त होने वाले UIView को छिपाएं और लेआउट की बाधाओं को स्वैप करें।

यदि आप इसे स्वयं नहीं लिखना चाहते हैं, तो एसबीपी नामक लेआउट की कमी के लिए एक पॉडफाइल है।

यहाँ एक ट्यूटोरियल है


0

अधिक उपयोग करने के लिए कोई ज़रूरत नहीं IBOutlet referenceके बजाय आप सीधे कर सकते हैं इस की बाधा के accessया updateपहले से ही लागू किया बाधा या तो द्वारा लागू Programmaticallyया से Interface Builderउपयोग कर किसी भी दृश्य पर KVConstraintExtensionsMasterपुस्तकालय। यह पुस्तकालय भी Cumulativeव्यवहार का प्रबंधन कर रहा है NSLayoutConstraint

कंटेनर व्यू पर ऊँचाई की बाधा जोड़ने के लिए

 CGFloat height = 200;
 [self.containerView applyHeightConstrain:height];

एनीमेशन के साथ कंटेनर व्यू की ऊँचाई बाधा को अद्यतन करने के लिए

[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
        if (expectedConstraint) {
            expectedConstraint.constant = 100;

            /* for the animation */ 
            [self.containerView  updateModifyConstraintsWithAnimation:NULL];
      }
    }];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.