चूँकि यह Google पर शीर्ष परिणाम है, मैंने सोचा कि मैं जो सबसे अधिक समझदार तरीका है उसे साझा करूँगा; जो iOS 7+ ट्रांस्फ़ॉर्मिंग API का उपयोग करने के लिए है। मैंने इसे स्विफ्ट 3 के साथ iOS 10 के लिए लागू किया।
UINavigationController
यदि आप एक उप-वर्ग बनाते हैं UINavigationController
और UIViewControllerAnimatedTransitioning
प्रोटोकॉल के अनुरूप होते हैं तो उस वर्ग का एक उदाहरण लौटाते हैं, जिसे दो दृश्य नियंत्रकों के बीच कैसे एनिमेट किया जाता है, इसे संयोजित करना बहुत सरल है ।
उदाहरण के लिए यहाँ मेरा UINavigationController
उपवर्ग है:
class NavigationController: UINavigationController {
init() {
super.init(nibName: nil, bundle: nil)
delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension NavigationController: UINavigationControllerDelegate {
public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return NavigationControllerAnimation(operation: operation)
}
}
आप देख सकते हैं कि मैंने UINavigationControllerDelegate
खुद को सेट किया है, और मेरे उपवर्ग पर विस्तार में मैं उस पद्धति को लागू करता हूं UINavigationControllerDelegate
जिससे आप एक कस्टम एनीमेशन नियंत्रक (यानी, NavigationControllerAnimation
) को वापस कर सकते हैं । यह कस्टम एनीमेशन कंट्रोलर आपके लिए स्टॉक एनीमेशन को बदल देगा।
आप शायद सोच रहे हैं कि मैं ऑपरेशन में NavigationControllerAnimation
इसके इनिशलाइज़र के माध्यम से क्यों गुजरता हूं । मैं ऐसा इसलिए करता हूं कि प्रोटोकॉल के NavigationControllerAnimation
कार्यान्वयन में UIViewControllerAnimatedTransitioning
मुझे पता है कि ऑपरेशन क्या है (यानी, 'पुश' या 'पॉप')। इससे यह जानने में मदद मिलती है कि मुझे किस तरह का एनीमेशन करना चाहिए। अधिकांश समय, आप ऑपरेशन के आधार पर एक अलग एनीमेशन करना चाहते हैं।
बाकी बहुत मानक है। UIViewControllerAnimatedTransitioning
प्रोटोकॉल और चेतन में दो आवश्यक कार्यों को लागू करें, लेकिन आप जैसे हैं:
class NavigationControllerAnimation: NSObject, UIViewControllerAnimatedTransitioning {
let operation: UINavigationControllerOperation
init(operation: UINavigationControllerOperation) {
self.operation = operation
super.init()
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else { return }
let containerView = transitionContext.containerView
if operation == .push {
// do your animation for push
} else if operation == .pop {
// do your animation for pop
}
}
}
यह याद रखना महत्वपूर्ण है कि प्रत्येक अलग प्रकार के ऑपरेशन के लिए (जैसे, 'पुश' या 'पॉप), से और देखने के लिए नियंत्रक अलग-अलग होंगे। जब आप एक पुश ऑपरेशन में होते हैं, तो नियंत्रक को देखने के लिए धक्का दिया जाएगा। जब आप किसी पॉप ऑपरेशन में होते हैं, तो कंट्रोलर देखने वाला वह होगा जिसे संक्रमण किया जा रहा है, और व्यू कंट्रोलर वह होगा जो पॉपप हो रहा है।
इसके अलावा, संक्रमण के संदर्भ में to
दृश्य नियंत्रक को उप-भाग के रूप में जोड़ा जाना चाहिए containerView
।
जब आपका एनीमेशन पूरा हो जाता है, तो आपको कॉल करना होगा transitionContext.completeTransition(true)
। आप एक इंटरैक्टिव संक्रमण कर रहे हैं, तो आप गतिशील रूप से एक वापस करने के लिए करना होगा Bool
करने के लिए completeTransition(didComplete: Bool)
संक्रमण एनीमेशन के अंत में पूरा हो गया है, तो के आधार पर,।
अंत में ( वैकल्पिक पठन ), आप यह देखना चाहते होंगे कि मैंने जिस संक्रमण पर काम कर रहा था, उसे कैसे किया। यह कोड थोड़ा अधिक हैकी है और मैंने इसे बहुत जल्दी लिखा है इसलिए मैं इसे महान एनीमेशन कोड नहीं कहूँगा लेकिन यह अभी भी दिखाता है कि एनीमेशन भाग को कैसे करना है।
मेरा एक बहुत ही सरल संक्रमण था; मैं उसी एनीमेशन की नकल करना चाहता था जो UINavigationController आम तौर पर करता है, लेकिन इसके बजाय 'अगला पृष्ठ ओवर द टॉप' एनीमेशन करता है, मैं पुराने दृश्य नियंत्रक के 1: 1 एनीमेशन को उसी समय लागू करना चाहता था जैसे कि नया दृश्य नियंत्रक प्रकट होता है। इससे दो दृश्य नियंत्रकों के रूप में ऐसा प्रतीत होता है कि जैसे वे एक दूसरे के लिए पिन किए जाते हैं।
पुश ऑपरेशन के लिए, जिसे toViewController
स्क्रीन के x- अक्ष पर मूल दृश्य को सेट करने की आवश्यकता होती है , इसे सब-वे के रूप में जोड़कर containerView
, इसे origin.x
शून्य पर सेट करके स्क्रीन पर एनिमेट कर रहा है। उसी समय, मैं स्क्रीन को बंद fromViewController
करके दृश्य को दूर करता हूं origin.x
:
toViewController.view.frame = containerView.bounds.offsetBy(dx: containerView.frame.size.width, dy: 0.0)
containerView.addSubview(toViewController.view)
UIView.animate(withDuration: transitionDuration(using: transitionContext),
delay: 0,
options: [ UIViewAnimationOptions.curveEaseOut ],
animations: {
toViewController.view.frame = containerView.bounds
fromViewController.view.frame = containerView.bounds.offsetBy(dx: -containerView.frame.size.width, dy: 0)
},
completion: { (finished) in
transitionContext.completeTransition(true)
})
पॉप ऑपरेशन मूल रूप से उलटा है। जोड़े toViewController
की एक subview के रूप containerView
है, और दूर चेतन fromViewController
सही करने के लिए के रूप में आप में चेतन toViewController
बाएं से:
containerView.addSubview(toViewController.view)
UIView.animate(withDuration: transitionDuration(using: transitionContext),
delay: 0,
options: [ UIViewAnimationOptions.curveEaseOut ],
animations: {
fromViewController.view.frame = containerView.bounds.offsetBy(dx: containerView.frame.width, dy: 0)
toViewController.view.frame = containerView.bounds
},
completion: { (finished) in
transitionContext.completeTransition(true)
})
यहाँ पूरी स्विफ्ट फ़ाइल के साथ एक जिस्ट है:
https://gist.github.com/alanzeino/603293f9da5cd0b7f6b60dc20bc766be