Bu Google'daki en iyi sonuç olduğu için en aklı başında olduğunu düşündüğüm şeyi paylaşacağımı düşündüm; iOS 7+ geçiş API'sını kullanmaktır. Swift 3 ile iOS 10 için bunu uyguladım.
Bunu, UINavigationControllerbir sınıfın alt sınıfını oluşturursanız UINavigationControllerve bir sınıfınUIViewControllerAnimatedTransitioningProtokolle .
Örneğin benim UINavigationControlleralt sınıfım:
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)
}
}
Kendine ayarladığımı görebilirsiniz UINavigationControllerDelegateve alt sınıfımdaki bir uzantıda, UINavigationControllerDelegateözel bir animasyon denetleyicisi (yani, NavigationControllerAnimation) döndürmenize izin veren yöntemi uygularım . Bu özel animasyon denetleyicisi sizin için stok animasyonunun yerini alacak.
Muhtemelen NavigationControllerAnimationbaşlatıcı aracılığıyla operasyona neden örneğe geçtiğimi merak ediyorsunuzdur . Bunu NavigationControllerAnimation,UIViewControllerAnimatedTransitioning (itme 'veya '' pop protokolü Ben operasyon yani) ne olduğunu biliyorum.' Bu ne tür bir animasyon yapmam gerektiğini bilmemize yardımcı olur. Çoğu zaman, işleme bağlı olarak farklı bir animasyon gerçekleştirmek istersiniz.
Gerisi oldukça standarttır. UIViewControllerAnimatedTransitioningProtokolde gerekli iki işlevi uygulayın ve istediğiniz gibi canlandırın:
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
}
}
}
Her farklı işlem türü için (yani, 'itme' veya 'pop) için görünümden ve görünümden denetleyicilerin farklı olacağını hatırlamak önemlidir. Bir itme işlemindeyken, görüntüleme denetleyicisi itilen kumanda olacaktır. Bir pop işlemindeyken, görünüm denetleyicisi, geçiş yapılan denetleyici, ve görünüm denetleyicisi de patlatılan denetleyici olacaktır.
Ayrıca, togörünüm denetleyicisi containerViewgeçiş bağlamında alt görünümü olarak eklenmelidir .
Animasyonunuz tamamlandığında aramalısınız transitionContext.completeTransition(true). Etkileşimli bir geçiş yapıyorsanız, dinamik bir geri dönmek zorunda kalacak Boolkadar completeTransition(didComplete: Bool)geçiş animasyon sonunda tamamlanıp tamamlanmadığını bağlı.
Son olarak ( isteğe bağlı okuma ), üzerinde çalıştığım geçişi nasıl yaptığımı görmek isteyebilirsiniz. Bu kod biraz daha hacky ve ben oldukça hızlı bir şekilde yazdım, bu yüzden harika bir animasyon kodu olduğunu söyleyemem ama yine de animasyon parçasının nasıl yapılacağını gösterir.
Benimki gerçekten basit bir geçişti; UINavigationController'ın yaptığı gibi aynı animasyonu taklit etmek istedim, ancak 'üstte bir sonraki sayfa' animasyonu yerine, yeni görünümle aynı anda eski görünüm denetleyicisinin 1: 1 animasyonunu uygulamak istedim denetleyici görünür. Bu, iki görünüm kontrolörünün birbirine sabitlenmiş gibi görünmesini sağlar.
İtme işlemi için, önce toViewControllerx ekseni kapalı ekranındaki görünümün başlangıcını ayarlamayı, alt görünümü olarak ekleyerek sıfıra containerViewayarlayarak ekranda canlandırmayı gerektirir origin.x. Aynı zamanda, ekranını kapatarak fromViewControllergörüntüsünü uzaklara hareket ettiriyorum 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)
})
Pop işlemi temelde tersidir. Ekle toViewControllerbir subview containerViewve uzak animasyon fromViewControllerİçinde animasyon olarak sağa toViewControllersoldan:
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)
})
İşte tüm hızlı dosyanın bir özeti:
https://gist.github.com/alanzeino/603293f9da5cd0b7f6b60dc20bc766be