このチュートリアルに従い、このテーマに関するWWDC ビデオを見ましたが、答えが見つかりませんでした。
私のコードにはほぼ同じ遷移があります。プッシュされたビューではなく、提示されたビューとして実行しているときはかなりうまく機能しています。
プッシュされたビューのスナップショットを CGRect からフルスクリーンにアニメーション化し、ポップしたときにその逆をアニメーション化することになっています。
これが私のUIViewControllerAnimatedTransitioning
クラスのコードです:
class ZoomingTransitionController: NSObject, UIViewControllerAnimatedTransitioning {
let originFrame: CGRect
let isDismissing: Bool
init(originFrame: CGRect, isDismissing: Bool) {
self.originFrame = originFrame
self.isDismissing = isDismissing
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return Constant.Animation.VeryShort
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else {
return
}
let finalFrame = transitionContext.finalFrame(for: toVC)
toVC.view.frame = finalFrame
let snapshot = self.isDismissing ? fromVC.view.snapshotView(afterScreenUpdates: true) : toVC.view.snapshotView(afterScreenUpdates: true)
snapshot?.frame = self.isDismissing ? finalFrame : self.originFrame
snapshot?.layer.cornerRadius = Constant.FakeButton.CornerRadius
snapshot?.layer.masksToBounds = true
containerView.addSubview(toVC.view)
containerView.addSubview(snapshot!)
if self.isDismissing {
fromVC.view.isHidden = true
} else {
toVC.view.isHidden = true
}
let duration = transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration,
animations: {
snapshot?.frame = self.isDismissing ? self.originFrame : finalFrame
},
completion: { _ in
if self.isDismissing {
fromVC.view.isHidden = false
} else {
toVC.view.isHidden = false
}
snapshot?.removeFromSuperview()
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
})
}
}
次に、2 つの方法を使用して新しい View Controller を表示しようとしました: 表示する方法とプッシュする方法です。
Myは と の両方をFromViewController
サブクラス化しています。UINavigationControllerDelegate
UIViewControllerTransitioningDelegate
FromViewController
を提示するクラスToViewController
(正常に動作します):
func buttonAction(_ sender: AnyObject) {
self.tappedButtonFrame = sender.frame
let toVC = self.storyboard!.instantiateViewController(withIdentifier: "ToViewController")
toVC.transitioningDelegate = self
self.present(toVC, animated: true, completion: nil)
}
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let transitionController = ZoomingTransitionController(originFrame: self.tappedButtonFrame, isDismissing: false)
return transitionController
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let transitionController = ZoomingTransitionController(originFrame: self.tappedButtonFrame, isDismissing: true)
return transitionController
}
FromViewController
クラスをプッシュしますToViewController
(これは機能しません):
func buttonAction(_ sender: AnyObject) {
self.tappedButtonFrame = sender.frame
let toVC = self.storyboard!.instantiateViewController(withIdentifier: "ToViewController")
self.navigationController?.pushViewController(toVC, animated: true)
}
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
switch operation {
case .push:
return ZoomingTransitionController(originFrame: self.tappedButtonFrame, isDismissing: false)
case .pop:
return ZoomingTransitionController(originFrame: self.tappedButtonFrame, isDismissing: true)
default:
return nil
}
}
を押すと、デリゲート メソッドが呼び出され、ZoomingTransitionController がそのコードを正常に実行します (animateTransition
特に問題なく最後まで実行されます)。しかし、画面上では、スナップショット ビューはどの時点でも表示されません。ToVC は移行期間の後に表示されますが、その間は何も表示されません。
これをデバッグする方法についてのアイデアが不足しています...何か考えはありますか?
ありがとう!!