博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 动画十五:Presentation Controller & Orientation Animations
阅读量:5930 次
发布时间:2019-06-19

本文共 3929 字,大约阅读时间需要 13 分钟。

UIKit 允许通过 delegate 模式(让主视图控制器采用UIViewControllerTransitioningDelegate)自定义 view controller 的模态视图弹出。

每次呈现新的视图控制器时,UIKit 都会询问其代理是否应该使用自定义 transition 。

UIKit 调用 animationController(forPresented:presents:source :) 来查看是否返回了 UIViewControllerAnimatedTransitioning。 如果该方法返回 nil,则 UIKit 使用内置转换。 如果 UIKit 接收 UIViewControllerAnimatedTransitioning 对象,则 UIKit 将该对象用作转换的动画控制器。

UIKit 首先要求自定义的 animation controller 以秒为单位给出 transition 持续时间,然后调用 animateTransition(using:),在该方法中我们可以可以访问屏幕上的 current view controller 以及将要显示的新 view controller,根据需要我们可以淡化(fade),缩放(scale),旋转(rotate)和操作(manipulate)现有 view 和新 view 。

Implementing transition delegates

创建集成于 NSObject 的类 PopAnimator 。该类将作为动画管理类。书写代码如下:

class PopAnimator: NSObject,UIViewControllerAnimatedTransitioning {       let duration = 1.0    var presenting = true    var originFrame = CGRect.zero    var dismissCompletion: (()->Void)?        func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {       return duration    }        func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {                let containerView = transitionContext.containerView        let toView = transitionContext.view(forKey: .to)!        containerView.addSubview(toView)        let herbView = presenting ? toView :            transitionContext.view(forKey: .from)!        let initialFrame = presenting ? originFrame : herbView.frame        let finalFrame = presenting ? herbView.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)// 宽缩放为原来的 xScaleFactor 倍,高缩放为原来 的yScaleFactor 倍,中心点位置不变                if presenting {            herbView.transform = scaleTransform            herbView.center = CGPoint( x: initialFrame.midX, y: initialFrame.midY)            herbView.clipsToBounds = true        }                containerView.addSubview(toView)        containerView.bringSubview(toFront: herbView)                UIView.animate(withDuration: duration, delay:0.0,                       usingSpringWithDamping: 0.4, initialSpringVelocity: 0.0, animations: {            herbView.transform = self.presenting ?               CGAffineTransform.identity : scaleTransform            herbView.center = CGPoint(x: finalFrame.midX, y: finalFrame.midY)        }, completion: { _ in            if !self.presenting {                self.dismissCompletion?()            }            transitionContext.completeTransition(true)        })    }    }复制代码
  1. 该类实现 UIViewControllerAnimatedTransitioning 协议。
  2. 方法 transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) 设定动画时间。
  3. 方法 animateTransition(using transitionContext: UIViewControllerContextTransitioning) 设置具体的动画效果。 xScaleFactor ,yScaleFactor 两行代码,检测初始和最终动画帧,然后计算在每个视图之间设置动画时需要在每个轴上应用的比例因子。

在 ViewController 中定义全局变量 let transition = PopAnimator() , 实现 UIViewControllerTransitioningDelegate 代理方法:

extension ViewController: UIViewControllerTransitioningDelegate {        func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {        transition.originFrame = selectedImage!.superview!.convert(selectedImage!.frame, to: nil)                transition.presenting = true        selectedImage!.isHidden = true                return transition    }        func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {        transition.presenting = false        return transition    }}复制代码

这样弹出模态视图的时候,就会执行 PopAnimator 管理类的动画了。

最终效果图:

转载于:https://juejin.im/post/5c3e8375f265da613a544079

你可能感兴趣的文章
get和post区别
查看>>
crontab执行shell脚本日志中出现乱码
查看>>
做移动互联网App,你的测试用例足够吗?
查看>>
cmd.exe启动参数说明
查看>>
《随笔记录》20170310
查看>>
网站分析系统
查看>>
一站式解决,Android 拍照 图库的各种问题
查看>>
lsof命令
查看>>
阿里云云计算ACP考试知识点(标红为重点)
查看>>
从零开始来看一下Java泛型的设计
查看>>
Shell编程基础
查看>>
Shell之Sed常用用法
查看>>
3.1
查看>>
校验表单如何摆脱 if else ?
查看>>
跨运营商组播传送案例(multicast-proxy-register应用)
查看>>
JTable的DefaultModel方法getValueAt(a,row)
查看>>
Good Bye 2013 A
查看>>
Automatic Sql Server Backup Utility Using sqlserveragent
查看>>
Java是如何读取和写入浏览器Cookies的
查看>>
篇一、安装配置Android Studio
查看>>