App Store卡片过渡动画模拟

19 篇文章 2 订阅
3 篇文章 0 订阅

iOS的原生应用都是设计师和工程师精心设计的,Weather的scrollview滚动动画,Settting的interaction交互式动画,App Store的Card过渡动画等等。都有很多我们值得学习的地方,今天我们模拟App Store的卡片动画

App Store动画模拟学习参考教程
自定义过渡动画教程
如何实现自定义过渡动画的方法不再讲述,这里直接实现动画过程。

参考动画效果

Today中的应用卡片,打开和关闭的效果。

实现动画效果

实现的效果也比较粗糙,有待改进,很多细节动画没有实现。

首先我们分析Present动画效果:

  1. 点击collectionView或者tableview的cell卡片。
  2. 卡片的大图逐渐放大形成卡片详情页的头图。
  3. 图片放大的过程中,详情页逐渐展示,右上角的按钮从透明到显现。

Dismisss过程是其反过程。

PushTranstionController

分析完动画过程,我们便可以开始实现动画。

import UIKit

class PushTranstionController: NSObject, UIViewControllerAnimatedTransitioning {
    
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 1.0
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromVC = transitionContext.viewController(forKey: .from) as? ViewController,
            let toVC = transitionContext.viewController(forKey: .to) as? DetailViewController,
            let selectedCell = fromVC.selectedCell else {
                return
        }
        
        let containerView = transitionContext.containerView
        let finalFrame = transitionContext.finalFrame(for: toVC)
        let frame = selectedCell.convert(selectedCell.imageView.frame, to: fromVC.view)
        toVC.view.frame = frame
        toVC.view.layer.cornerRadius = 15
        toVC.view.layer.masksToBounds = true
        toVC.topImageView.frame.size.width = ScreenWidth - 60
        toVC.topImageView.frame.size.height = 400
        
        containerView.addSubview(toVC.view)
        
        let duration = transitionDuration(using: transitionContext)
        
        
        UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations:
            {
                toVC.view.frame = finalFrame
                toVC.topImageView.frame.size.width = ScreenWidth
                toVC.topImageView.frame.size.height = ScreenHeight * 0.55
                toVC.closeBtn.alpha = 1
        }) { (_) in
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
    

}

ViewController为卡片控制器,DetailViewController为卡片详情控制器。
注意:这里需要在卡片控制器设置selectedCell关键属性,用于动画控制器获取被点击cellframe模型。

代码实现过程:

  1. 动画资源准备。获取fromVCtoVCfromVC.selectedCell。获取过渡语境的containerView,视图控制器的最终大小finalFrame,点击cellimageView在源视图的frame(强调:这里的frame不是cell的imageView在cellframe而是在源视图坐标系下的frame)等。
  2. 动画初始化设置。将详情页的frame设置为卡片的frame,设置圆角,设置头图的size缩小为大图的size
  3. 创建动画。使用弹性动画,详情页frame更新(对应逐渐放大),头图size还原,按钮实化。

PopTransitionController

pop动画为其反过程。这里贴出代码。

class PopTransitionController: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.5
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let fromVC = transitionContext.viewController(forKey: .from) as? DetailViewController,
            let toVC = transitionContext.viewController(forKey: .to) as? ViewController,
            let selectedCell = toVC.selectedCell else {
                return
        }
        
        let containerView = transitionContext.containerView
        containerView.insertSubview(toVC.view, at: 0)
        let frame = selectedCell.convert(selectedCell.imageView.frame, to: toVC.view)
        
        let duration = transitionDuration(using: transitionContext)
        toVC.view.isHidden = true
        UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: [], animations:
            {
                fromVC.view.frame = frame
                fromVC.view.layer.cornerRadius = 15
                fromVC.view.layer.masksToBounds = true
                fromVC.topImageView.frame.size.width = ScreenWidth - 60
                fromVC.topImageView.frame.size.height = 400
                fromVC.closeBtn.alpha = 0
        }) { (_) in
            toVC.view.isHidden = false
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        }
    }
    
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值