路漫漫其修远兮,吾将上下而求索,本文主要讲述AppStore首页转场动画 demo: 自定义动画 这里用的push ,pop 两个协议UINavigationControllerDelegate UIViewControllerAnimatedTransitioning
push代码
//MARK: - -运用本类的跳转动画
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?{
return self
}
//MARK: - - 动画市场
functransitionDuration(using transitionContext:UIViewControllerContextTransitioning?) ->TimeInterval{
return1.0
}
//MARK: - -动画核心代码
funcanimateTransition(using transitionContext:UIViewControllerContextTransitioning) {
//去向
lettoVC = transitionContext.viewController(forKey: .to)as!ZHViewController
varcell :HomePageCell?
if let index = myTableView.indexPathForSelectedRow {
cell =myTableView.cellForRow(at: index)as?HomePageCell
}
//为动画做准备
letfromView = cell?.header
lettoView = toVC.headImageView
// 容器
letcontainerView = transitionContext.containerView
//最终去向vc view的frame
toVC.view.frame= transitionContext.finalFrame(for: toVC)
letcustomImageView =UIImageView(image: cell?.header.image)
if letfromVieww = fromView{
customImageView.frame= containerView.convert(fromVieww.frame, from: fromView?.superview)
}
//为动画做准备
lettitleLabel =UILabel()
titleLabel.text= toVC.titleStr1
titleLabel.font=UIFont.systemFont(ofSize:20, weight: .medium)
titleLabel.textColor= .white
titleLabel.frame=CGRect(x:15, y:50, width:SCREEN_WIDTH-30, height:21)
customImageView.addSubview(titleLabel)
lettitleTwoLabel =UILabel()
titleTwoLabel.text= toVC.titleStr2
titleTwoLabel.textColor= .white
titleTwoLabel.font=UIFont.systemFont(ofSize:18, weight: .medium)
titleTwoLabel.frame=CGRect(x:15, y:SCREEN_WIDTH*1.5-15-21, width:SCREEN_WIDTH-30, height:21)
customImageView.addSubview(titleTwoLabel)
// 反转过程中展示的
containerView.addSubview(toVC.view)
containerView.addSubview(customImageView)
fromView?.isHidden=true
toVC.view.alpha=0
toView?.isHidden=true
//动画开始
UIView.animate(withDuration:self.transitionDuration(using: transitionContext), delay:0, usingSpringWithDamping:0.6, initialSpringVelocity:1.0, options: .curveEaseIn, animations: {
toVC.view.alpha=1
containerView.layoutIfNeeded()
customImageView.frame= containerView.convert(toView!.frame, from: toView?.superview)
}) { (finish)in
//跳转完 删除 过渡时的控件 展示页面
fromView?.isHidden=false
toVC.view.isHidden=false
toView?.isHidden=false
customImageView.removeFromSuperview()
// 动画结束 告诉上下文
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
pop 代码
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning?{
return self
}
//MARK: - -手势只有在UIScrollView上识别
funcgestureRecognizer(_gestureRecognizer:UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer:UIGestureRecognizer) ->Bool{
if let onView = otherGestureRecognizer.view, onView.isKind(of:UIScrollView.self){
return true
}
return false
}
//MARK: - -动画时长
functransitionDuration(using transitionContext:UIViewControllerContextTransitioning?) ->TimeInterval{
return1.0
}
//MARK: - -核心动画
funcanimateTransition(using transitionContext:UIViewControllerContextTransitioning) {
// 从这里
letfromVC = transitionContext.viewController(forKey: .from)as!ZHViewController
//到这里
lettoVC = transitionContext.viewController(forKey: .to)as!HomePageVC
//从这个vc
letfromView =headImageView
//临时容器 这里有个重要的概念containerView,要做转场动画的视图就必须要加入containerView上才能进行,可以理解containerView管理着所有做转场动画的视图
letcontainerView = transitionContext.containerView
var cell :HomePageCell?
ifletindex =selectIndexPath{
cell = toVC.myTableView.cellForRow(at: index)as?HomePageCell
}
lettoView = cell?.header
//截屏
letsnapShotView = fromView?.snapshotView(afterScreenUpdates:false)
snapShotView?.layer.masksToBounds=true
snapShotView?.layer.cornerRadius=15
snapShotView?.frame = containerView.convert(fromView!.frame, from: fromView?.superview)
// 加载到临时容器 让跳转动画有痕迹
containerView.insertSubview(toVC.view, belowSubview: fromVC.view)
containerView.addSubview(snapShotView!)
//title
snapShotView?.addSubview(titleLabel!)
snapShotView?.addSubview(titleTwoLabel!)
toView?.isHidden=true
fromView?.isHidden=true
UIView.animate(withDuration:self.transitionDuration(using: transitionContext), delay:0, usingSpringWithDamping:0.5, initialSpringVelocity:0.8, options: .curveEaseInOut, animations: {
containerView.layoutIfNeeded()
self.myScrollView.layoutIfNeeded()
fromVC.view.alpha=0.0
snapShotView?.layer.cornerRadius=15
self.myScrollView.frame=CGRect(x: self.myScrollView.frame.origin.x, y: self.myScrollView.frame.origin.y, width: self.myScrollView.frame.size.width, height:SCREEN_WIDTH*1.5*0.8)
self.myScrollView.layer.cornerRadius=15
snapShotView?.frame= containerView.convert(toView!.frame, from: toView?.superview)//临时的
}) { (finish)in
fromView?.isHidden=true
snapShotView?.removeFromSuperview()
toView?.isHidden=false
//动画结束告诉上下文
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
网友评论