UIStackView Hide एनिमेशन देखें


83

IOS 11 में a के भीतर छिपा एनीमेशन का व्यवहार UIStackView बदल गया है, लेकिन मैं कहीं भी इस दस्तावेज को खोजने में असमर्थ रहा हूं।

iOS 10

iOS 10 एनीमेशन

iOS 11

iOS 11 एनीमेशन

दोनों में कोड यह है:

UIView.animate(withDuration: DiscoverHeaderView.animationDuration,
                       delay: 0.0,
                       usingSpringWithDamping: 0.9,
                       initialSpringVelocity: 1,
                       options: [],
                       animations: {
                            clear.isHidden = hideClear
                            useMyLocation.isHidden = hideLocation
                        },
                       completion: nil)

मैं iOS 11 पर पिछले व्यवहार को कैसे पुनर्स्थापित करूं?

जवाबों:


133

बस एक ही मुद्दा था। फिक्स stackView.layoutIfNeeded()एनीमेशन ब्लॉक के अंदर जोड़ रहा है। stackViewउन मदों का कंटेनर कहां है जिसे आप छिपाना चाहते हैं।

UIView.animate(withDuration: DiscoverHeaderView.animationDuration,
                   delay: 0.0,
                   usingSpringWithDamping: 0.9,
                   initialSpringVelocity: 1,
                   options: [],
                   animations: {
                        clear.isHidden = hideClear
                        useMyLocation.isHidden = hideLocation
                        stackView.layoutIfNeeded()
                    },
                   completion: nil)

यह निश्चित नहीं है कि यह अचानक iOS 11 में एक मुद्दा क्यों है लेकिन निष्पक्ष होने के लिए यह हमेशा अनुशंसित दृष्टिकोण रहा है।


1
आप एक नायक हैं: D
Infinity James

5
उपयुक्त नाम 'स्प्रिंगहैम'
James

4
आईओएस में <= 10 वहाँ एक बग, जिसमें सेटिंग थी hiddenएक की संपत्ति UIStackViewकी subviewएनीमेशन ब्लॉक में कुछ मामलों में ध्यान नहीं दिया जा रहा था, इसलिए सबसे अच्छा तरीका है सही एनीमेशन से पहले इसके बारे में बाहर इसे बदलने के लिए, है।
इयूलियन ओनोफ्रेई

2
मेरी ओर से एक गलतफहमी हो सकती है, लेकिन यह डॉक्स से नहीं लगता है जैसे view.layoutIfNeeded()कि स्टैक व्यू में अन्य विचारों की स्थिति को अपडेट करेगा जो हम चाहते हैं। developer.apple.com/documentation/uikit/uiview/...
एक Springham

6
view.layoutIfNeeded () ठीक है, फिर भी view.isHidden को कॉल करना = सही है यदि दृश्य पहले से छिपा हुआ है (या विपरीत) चीज़ को तोड़ते हैं। इसलिए यह देखना सुनिश्चित करें कि क्या वह दृश्य पहले से छिपा हुआ राज्य नहीं है जिसे आप बदलना चाहते हैं। if (view.isHidden == true) {view.isHidden = false}
glemoulant

5

स्विफ्ट 4 एक्सटेंशन:

// MARK: - Show hide animations in StackViews

extension UIView {

func hideAnimated(in stackView: UIStackView) {
    if !self.isHidden {
        UIView.animate(
            withDuration: 0.35,
            delay: 0,
            usingSpringWithDamping: 0.9,
            initialSpringVelocity: 1,
            options: [],
            animations: {
                self.isHidden = true
                stackView.layoutIfNeeded()
            },
            completion: nil
        )
    }
}

func showAnimated(in stackView: UIStackView) {
    if self.isHidden {
        UIView.animate(
            withDuration: 0.35,
            delay: 0,
            usingSpringWithDamping: 0.9,
            initialSpringVelocity: 1,
            options: [],
            animations: {
                self.isHidden = false
                stackView.layoutIfNeeded()
            },
            completion: nil
        )
    }
}
}

5
मेरे लिए यह तय करना था self.isHiddenकि अगर पहले से ही समान है तो मूल्य निर्धारित न करें।
अमीर

1
यह आसानी से 1 फ़ंक्शन हो सकता है जिसे toggleAnimated (... में, शो: बूल) कहा जाता है। चूँकि केवल एक ही लाइन बदलती है :) साथ ही यह मेरे लिए काम नहीं करता है: s
जीन रेमंड डाहर

हां, सिंगल
फंक

4

यह पहले से ही स्वीकृत उत्तर की टिप्पणियों में उल्लिखित है, लेकिन यह मेरी समस्या थी और यह यहाँ किसी भी उत्तर में नहीं है:

पहले से छिपे हुए दृश्य पर कभी भी सेट करें isHidden = true। यह स्टैक दृश्य को गड़बड़ कर देगा।


यह मेरी समस्या थी, और मुझे फोन करने की आवश्यकता नहीं थी layoutIfNeededइसलिए मुझे आश्चर्य है कि अगर यह सही उत्तर होना चाहिए।
बी रॉय डावसन

3

मैं इस फ़ंक्शन को साझा करना चाहता हूं, जो छिपाने और कई दृश्यों को दिखाने के लिए अच्छा है UIStackView, क्योंकि मैंने पहले उपयोग किए गए सभी कोड को सुचारू रूप से काम नहीं किया, क्योंकि किसी को कुछ परतों से हटाने की आवश्यकता है:

extension UIStackView {
    public func make(viewsHidden: [UIView], viewsVisible: [UIView], animated: Bool) {
        let viewsHidden = viewsHidden.filter({ $0.superview === self })
        let viewsVisible = viewsVisible.filter({ $0.superview === self })

        let blockToSetVisibility: ([UIView], _ hidden: Bool) -> Void = { views, hidden in
            views.forEach({ $0.isHidden = hidden })
        }

        // need for smooth animation
        let blockToSetAlphaForSubviewsOf: ([UIView], _ alpha: CGFloat) -> Void = { views, alpha in
            views.forEach({ view in
                view.subviews.forEach({ $0.alpha = alpha })
            })
        }

        if !animated {
            blockToSetVisibility(viewsHidden, true)
            blockToSetVisibility(viewsVisible, false)
            blockToSetAlphaForSubviewsOf(viewsHidden, 1)
            blockToSetAlphaForSubviewsOf(viewsVisible, 1)
        } else {
            // update hidden values of all views
            // without that animation doesn't go
            let allViews = viewsHidden + viewsVisible
            self.layer.removeAllAnimations()
            allViews.forEach { view in
                let oldHiddenValue = view.isHidden
                view.layer.removeAllAnimations()
                view.layer.isHidden = oldHiddenValue
            }

            UIView.animate(withDuration: 0.3,
                           delay: 0.0,
                           usingSpringWithDamping: 0.9,
                           initialSpringVelocity: 1,
                           options: [],
                           animations: {

                            blockToSetAlphaForSubviewsOf(viewsVisible, 1)
                            blockToSetAlphaForSubviewsOf(viewsHidden, 0)

                            blockToSetVisibility(viewsHidden, true)
                            blockToSetVisibility(viewsVisible, false)
                            self.layoutIfNeeded()
            },
                           completion: nil)
        }
    }
}

इससे विचारों के लुप्त होने / न निकलने के मुद्दे का भी समाधान हुआ। सुंदर!
पेट्र फियाल

3

एकल तत्वों को छिपाने / दिखाने के लिए विस्तार

यह 100% संबंधित नहीं है, लेकिन यदि आप एकल UIViewतत्वों को छिपाने के लिए एक संक्षिप्त तरीका ढूंढ रहे हैं (या तो स्टैक दृश्य या कहीं और), तो आप मेरे द्वारा बनाए गए इस सरल एक्सटेंशन का उपयोग कर सकते हैं:

extension UIView {
    func isHiddenAnimated(value: Bool, duration: Double = 0.2) {
        UIView.animate(withDuration: duration) { [weak self] in self?.isHidden = value }
    }
}

मैं इसे कोड की एक पंक्ति के साथ स्टैक व्यू में एनीमेशन के साथ तत्वों को आसानी से छिपाने / दिखाने के लिए उपयोग करता हूं। उदाहरण:

validatableButton.isHiddenAnimated(value: false)

1

आशा है कि यह दूसरों को कुछ घंटों की निराशा से बचाता है।

एक ही समय में कई UIStackView सबव्यू को छुपाना और दिखाना एक गड़बड़ है।

कुछ मामलों में .isHidden एनिमेशन ब्लॉक में परिवर्तन अगले एनीमेशन तक सही ढंग से प्रदर्शित होता है, तब .isHidden को अनदेखा किया जाता है। इसके लिए मैंने जो एकमात्र विश्वसनीय ट्रिक पाया है, वह एनीमेशन ब्लॉक के पूरा होने के अनुभाग में .isHidden निर्देशों को दोहराना है।

    let time = 0.3

    UIView.animate(withDuration: time, animations: {

        //shows
        self.googleSignInView.isHidden = false
        self.googleSignInView.alpha = 1
        self.registerView.isHidden = false
        self.registerView.alpha = 1

        //hides
        self.usernameView.isHidden = true
        self.usernameView.alpha = 0
        self.passwordView.isHidden = true
        self.passwordView.alpha = 0

        self.stackView.layoutIfNeeded()

    }) { (finished) in

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