答案 0 :(得分:1)
我前段时间写了一篇关于如何制作自定义过渡和动画的博客文章,尽管这更像是App Store的指南,它可以用于任何类型的过渡动画。
https://medium.com/@eric.dockery283/custom-view-transitions-like-the-new-app-store-a2a1181229b6
要研究的事项是UIViewControllerAnimatedTransitioning
总之,您需要2个视图控制器作为动画的登录视图控制器和结束状态视图控制器。您将使用UIViewControllerAnimatedTransitioning来处理从一个视图控制器到另一个视图控制器的转换。我的例子是:
import UIKit
class TransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
let durationExpanding = 0.75
let durationClosing = 0.5
var presenting = true
var originFrame = CGRect.zero
var dismissCompletion: (()->Void)?
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
if presenting {
return durationExpanding
}
return durationClosing
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let toView = transitionContext.view(forKey: .to), let detailView = presenting ? toView: transitionContext.view(forKey: .from) else {
return
}
let initialFrame = presenting ? originFrame : detailView.frame
let finalFrame = presenting ? detailView.frame : originFrame
let xScaleFactor = presenting ? initialFrame.width / finalFrame.width : finalFrame.width / initialFrame.width
let yScaleFactor = presenting ? initialFrame.height / finalFrame.height : finalFrame.height / initialFrame.height
let scaleTransform = CGAffineTransform(scaleX: xScaleFactor,
y: yScaleFactor)
if presenting {
detailView.transform = scaleTransform
detailView.center = CGPoint( x: initialFrame.midX, y: initialFrame.midY)
detailView.clipsToBounds = true
}
containerView.addSubview(toView)
containerView.bringSubview(toFront: detailView)
if presenting {
//update opening animation
UIView.animate(withDuration: durationExpanding, delay:0.0,
usingSpringWithDamping: 1.0, initialSpringVelocity: 0.0, //gives it some bounce to make the transition look neater than if you have defaults
animations: {
detailView.transform = CGAffineTransform.identity
detailView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
},
completion:{_ in
transitionContext.completeTransition(true)
}
)
} else {
//update closing animation
UIView.animate(withDuration: durationClosing, delay:0.0, options: .curveLinear,
animations: {
detailView.transform = scaleTransform
detailView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)
},
completion:{_ in
if !self.presenting {
self.dismissCompletion?()
}
transitionContext.completeTransition(true)
}
)
}
}
}
您需要在登录视图控制器中设置转换委托:
extension ViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
guard let originFrame = selectedCell.superview?.convert(selectedCell.frame, to: nil) else {
return transition
}
transition.originFrame = originFrame
transition.presenting = true
selectedCell.isHidden = true
return transition
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transition.presenting = false
return transition
}
}
这应该允许您以您需要的方式自定义您的视图/动画。