ios - रोटेशन पूर्ण होने के बाद आकार के तत्व के आधार पर डिवाइस रोटेशन के दौरान परिवर्तनों को चेतन करना होगा




swift ios8 (2)

मेरे पास एक गतिशील सेटअप है जो एक स्टोरीबोर्ड में सेट किए गए ऑटो लेआउट प्रतिबंधों के आधार पर स्वचालित रूप से चौड़ाई और ऊंचाई में समायोजित करते हैं। जब पोर्ट्रेट में बटन के बराबर चौड़ाई और ऊंचाइयों होते हैं तो फ़्रेम पूरी तरह से चौकोर होता है, और जब उपकरण परिदृश्य में घुमाया जाता है तो बटन छोटे और व्यापक होते हैं। मैंने बटन परतों पर cornerRadius सेट किया है, इसलिए वे पूरी तरह से परिपत्र हैं जब पोर्ट्रेट में और वह अच्छी तरह से काम करता है, लेकिन जब मैं परिदृश्य में घुमाएगा तो कोने त्रिज्या सही और न ही सही लगती है मुझे इसे बदलने की जरूरत है, इसलिए यह एक अंडाकार बन जाता है समस्या यह है, कोई बात नहीं है कि मैं उस कोड को लगाने का प्रयास क्यों करता हूं, मुझे सही चौड़ाई और ऊंचाई नहीं मिल सकती है, क्योंकि रोटेशन होने के बाद बटन होंगे। मुझे यह चाहिए कि डिवाइस को घुमाया जा रहा है, जबकि - रोटेशन पूरा होने तक इंतजार नहीं करना चाहता। मुख्य रूप से cornerRadius बदलाव को चेतन करेगा, जबकि संक्रमण एनिमेटेड होगा।

अगर मैं viewWillLayoutSubviews या viewDidLayoutSubviews उपयोग करता हूं, यह एप्लिकेशन को लॉन्च करने पर बटन फ्रेम को सही तरीके से प्राप्त करता है, लेकिन परिदृश्य के घूर्णन पर इस विधि को बटन के फ़्रेम को नए अभिविन्यास के लिए अपडेट करने से पहले कहा जाता है, इसलिए मैं सही कोने के त्रिज्या की गणना नहीं कर सकता

यदि मैं viewWillTransitionToSize:withTransitionCoordinator: उपयोग करता हूं viewWillTransitionToSize:withTransitionCoordinator: willTransitionToTraitCollection:withTransitionCoordinator: या willRotateToInterfaceOrientation willTransitionToTraitCollection:withTransitionCoordinator: या willRotateToInterfaceOrientation , यह ऐप लॉन्च होने पर कॉल नहीं किया जाता है, और डिवाइस को घूर्णन करने पर इसे फ्रेम कहा जाता है इससे पहले कि इसे नए आकार के लिए अपडेट किया जाता है।

अगर मैं willAnimateRotationToInterfaceOrientation उपयोग करता willAnimateRotationToInterfaceOrientation , तो ऐप लॉन्च होने पर इसे नहीं कहा जाता है, लेकिन डिवाइस को घूर्णन करने पर यह सही ढंग से नया बटन फ़्रेम प्राप्त करता है। लेकिन यह विधि नापसंद है।

तो सवाल यह है कि आप किस आकार का बटन बटन के गुणों को सेट करने के लिए इस्तेमाल कर सकते हैं, जब रोटेशन पूरा हो जाएगा, जिसे रोटेशन पूरा होने से पहले कहा जाता है?

ध्यान दें कि इसे हर ओरिएंटेशन परिवर्तन के लिए बुलाया जाना चाहिए, बल्कि न केवल आकार वर्ग के परिवर्तन (आईपीए घूर्णन आकार वर्ग को बदलना नहीं)। मुझे केवल आईओएस 8.0+ का समर्थन करने की ज़रूरत है

यह वह कोड है जिसे मैं यह जानना चाहता हूँ कि क्या सही आकार मिल रहा है:

println("\(button.frame.size.width) x \(button.frame.size.height)")

जवाब देखने का उपयोग करने के लिए है viewWillTransitionToSize:withTransitionCoordinator: आपके कोड को animateAlongsideTransition: बंद करने के अंदर UIViewControllerTransitionCoordinator के animateAlongsideTransition: विधि। यह आपको आकार के आधार पर परिवर्तनों को चेतन करने की अनुमति देगा, जब यह रोटेशन पूर्ण हो जाएगा।

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    coordinator.animateAlongsideTransition({ (context: UIViewControllerTransitionCoordinatorContext!) -> Void in
        self.updateButtonsCornerRadius()
    }, completion: nil)
}

इस पद्धति को तब नहीं कहा जाता है जब ऐप लॉन्च करता है, हालांकि आप स्वयं को देखने के लिए चाहते हैं। self.updateButtonsCornerRadius() viewDidLoad में भी।


नीचे मैं एनीमेशन के प्रत्येक फ्रेम के दौरान गुणों को अपडेट करने के लिए CADisplayLink का उपयोग कैसे कर सकता CADisplayLink , लेकिन एक आसान तरीका है। लेआउट के साथ बटन (या देखें या जो भी) उप-वर्ग को देखें, जो कि किनारे के त्रिज्या को अपडेट करता है:

class RoundedCornerView: UIView {

    override func layoutSubviews() {
        super.layoutSubviews()

        layer.cornerRadius = min(bounds.width, bounds.height) / 2
    }

}

फिर, एनीमेशन के दौरान, फ्रेम आकार में परिवर्तन के रूप में, कोने त्रिज्या स्वचालित रूप से अपडेट होता है:

जैसा कि जॉय बताते हैं, किसी नए आकार की अधिसूचना को देखने के लिए उपयोग किया जा सकता है, और फिर मुख्य एनीमेशन के साथ अपने अतिरिक्त एनीमेशन का समन्वय करने के लिए animateAlongsideTransition का उपयोग करें।

यदि आप किसी अन-एनिमेटबल प्रॉपर्टी को चेतन करना चाहते हैं, जैसे कोने त्रिज्या (ब्लॉक-आधारित एनिमेशन में, वैसे भी), तो आप एनीमेशन की अवधि के लिए एक प्रदर्शन लिंक का उपयोग कर सकते हैं। यह प्रभावी रूप से रोटेशन एनीमेशन के प्रत्येक फ्रेम के लिए हमारी विधि को कॉल करता है इस प्रकार, हमारे पास एक ऐसा तरीका होगा जो प्रस्तुति स्तर पर दिखता है (जो आपको मध्य एनीमेशन के एक स्तर की वर्तमान स्थिति दिखाता है) को उड़ने पर कोने के त्रिज्या समायोजित करने के लिए। आप इस के लिए animateAlongsideTransition भी उपयोग कर सकते हैं, लेकिन हम इस मामले में animation क्लोजर का उपयोग नहीं कर रहे हैं, बल्कि animation में जानने के completion होने के completion होने के साथ ही प्रदर्शन लिंक को रोक भी सकते हैं:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)

    let displayLink = CADisplayLink(target: self, selector: "handleDisplayLink:")
    displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)

    coordinator.animateAlongsideTransition(nil) { (context) -> Void in
        displayLink.invalidate()
    }
}

func handleDisplayLink(displayLink: CADisplayLink) {
    updateButtonsCornerRadius()
}

func updateButtonsCornerRadius() {
    for button in [button1, button2] {
        let presentationLayer = button.layer.presentationLayer() as CALayer
        let minDimension = min(presentationLayer.frame.size.width, presentationLayer.frame.size.height)
        button.layer.cornerRadius = minDimension / 2.0
    }
}

सच कहूँ, मुझे यकीन नहीं है कि इस कोने त्रिज्या एनीमेशन इस डिस्प्ले लिंक को सही ठहराने के लिए पर्याप्त है (मुझे सिम्युलेटर में एंबेन्सेशन को कमांड + टी के साथ अंतर की सराहना करने के लिए धीमा करना पड़ा), लेकिन यह मूल विचार को दिखाता है





size-classes