Swit轉場動畫的簡單分析

2024-05-10 09:08
文章标签 分析 簡單 動畫 swit 轉場

本文主要是介绍Swit轉場動畫的簡單分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先, 我們得了解什麼是轉場動畫. 

1. 轉場動畫即是對一個view呈現和關閉時所做的動畫, 叫轉場動畫. 

動畫是如何做出來的呢?

一. 了解CALayer與CGContext和UIView之間的關係

1. 以前我們學習UIView的時候, 應該知道, 當創建一個UIView的時候,系統會默認將UIView的LayerClass設置為layer類型.那麼什麼是layer呢?

 -1.1 layer即是圖層, 是CALayer類型的實例. 而CALayer包含在QuartzCore框架中,這是一個跨平台的框架,即可以用在ios中又可以用在Mac OS X中.在使用Core Animation開發動畫的本質就是將CALayer中的內容轉化為位圖從而供硬件操作,所以要熟練掌握動畫操作必須先熟悉CALayer.

-1.2 又多一個問題了, 那麼CALayer是什麼?首先, UIView有一個屬性是layer, 在這個屬性有下面這麼一段注析

: public var layer: CALayer { get } // returns view's layer. Will always return a non-nil value. view is layer's delegate
很明顯, 這個屬性返回一個layer, 並且當前View是這個Layer的代理. 那麼既然是代理, 說明當前view可以實現Layer的代理方法來對當前view的layer進行操作.
那麽就探一下CALayer內部都有些啥東西: 
public init()
public init(layer: AnyObject)
public func presentationLayer() -> AnyObject?
public func modelLayer() -> AnyObject
public class func defaultValueForKey(key: String) -> AnyObject?
public class func needsDisplayForKey(key: String) -> Bool
public func shouldArchiveValueForKey(key: String) -> Bool
public var bounds: CGRect
public var position: CGPoint
等等......太多了就不列出來了, 這裡只做個簡單的分析. 
很明顯CALayer內部的方法都是用來操作layer的一些構造方法,屬性等. 至上而下可以很清晰的明白,CALayer不是UIKit的東西, 是在QuartzCore框架下聲明的一個類. 
-1.3 說這麼多, 那麼layer到底有什麼作用?
首先我們通過CALayer的一個代理方法來說明下:
override func drawLayer(layer: CALayer, inContext ctx: CGContext)
通過這個代理方法, 可以對圖層進行繪製. 我kao, 這裡有多了一個CGContext的類, 有是神馬東西? 讓我們來逐步分析:
CGContext ctx : 圖形上下文
CALayer layer: 當前layer
通過上面的代理方法, 可以拿到圖形上下文, 而圖形上下文裡面存放著當前layer繪製圖形的所有數據, 既然是專門用來繪製圖形的上下文, 那麼我們只要通過對上下文內的數據進行需修改, 就可以完成在layer上面的繪製. 說到這裡應該很清晰了吧?讓我們直接點進去CGContext裡面看看有什麼方法可以用來修改上下文的數據: 
public func CGContextScaleCTM(c: CGContext?, _ sx: CGFloat_ sy: CGFloat)
@available(iOS 2.0, *)
public func CGContextTranslateCTM(c: CGContext?, _ tx: CGFloat_ ty: CGFloat)
等等...這裡不一一列出來了, 因為太多了, 這裡只做簡單分析. 很明顯, 這兩個方法是通過傳入一個 c : 上下文 , 再通過傳入參數對上下文內的數據進行修改來繪製Scale和Translate. 

好了,讓我們總結一下layer的作用吧. 通過上面一些雜亂東西的分析,layer其實就是一個畫板, 通過CALayer內部的方法可以修改畫板的一些基本屬性, 通過CALayer的代理方法可以拿到畫板繪製圖形的各種數據, 通過對圖形上下文數據的修改來進行圖片繪製,並且最終畫在Layer上.說白了, Layer就是一個用來呈現圖形的畫板,沒有Layer, 就看不見任何東西.

二. 轉場動畫的實現

上面第一點也說了, 轉場動畫是View呈現和關閉的時候的過渡動畫.
很簡單, 既然是View的動畫,我們可以通過UIView提供的動畫方法來實現: 
@available(iOS 4.0, *)
    public class func animateWithDuration(duration: NSTimeInterval, delay: NSTimeInterval, options: UIViewAnimationOptions, animations: () -> Void, completion: ((Bool) -> Void)?)
@available(iOS 4.0, *)
    public class func animateWithDuration(duration: NSTimeInterval, animations: () -> Void, completion: ((Bool) -> Void)?)
@available(iOS 4.0, *)
    public class func animateWithDuration(duration: NSTimeInterval, animations: () -> Void)
@available(iOS 4.0, *)
    public class func transitionWithView(view: UIView, duration: NSTimeInterval, options: UIViewAnimationOptions, animations: (() -> Void)?, completion: ((Bool) -> Void)?)
等等, 這些都是UIView內部提供的實現動畫的方法.但是這些方法並不能滿足我們的全部需求,因為在modal一個控制器的時候, 我們可以通過這些方法控制View在即將顯示和正在顯示的這段時間內做動畫, 而不能對控制器,View和ContainerView進行操作.對控制器的呈現和關閉做一個自定義的動畫, 即是轉場動畫.
我靠, 這裡又多了一個ContainerView, 又是神馬東西? 
ContainerView: 容器視圖, 用於存放動畫所需要的控件,所有跟動畫有關的控件都放在裡面.
好, 讓我們舉個例子來簡單的說明Swift中轉場動畫的使用.我盡量說得詳細點, 耐心看下去就懂了.
需求: 在一個NavigationBar控制器上點擊RightButton, 呈現一個自定義尺寸,動畫的控制器.
分析: 首先控制器的層級結構是 UIWindow -> RootViewController -> UINavigationController
此時我們需要了解幾個UIViewController中的屬性: 
1.presentedViewController: 這是一個被當前控制器或者其最近的父控制器所modal的控制器
2.presentingViewController: presentedViewController的根控制器, 即最遠的祖先控制器
3.transitioningDelegate : UIViewControllerTransitioningDelegate : 轉場動畫代理

好, 既然UIViewController提供了一個轉場動畫的代理, 那麼我們只需要實現下代理方法, 即可以完成轉場動畫了. 好像很快要實現動畫了, 很緊張的趕腳.
第一步:
首先創建一個類, 並且讓它成為transitioningDelegate的代理
第二步:
實現代理方法:

1作用: 當自定義顯示控制器(UIPresentationController)呈現一個控制器時管理視圖層次結構, 向代理發送請求. (這個自定義顯示控制器(UIPresentationCtroller)是用來管理modal的顯示佈局)
參數: 這個方法需要我們返回一個UIPresentationController的實例
運用: 接下來,我們需要手動創建一個UIPresentationController實例,並且實現其內部構造方法來對modal控制器的佈局, 最後返回該對象即可.
1. func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController, sourceViewController source: UIViewController) -> UIPresentationController?
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2作用:返回一個遵守UIViewControllerAnimatedTransitioning協議的對象, 設置在控制器 呈現的時候通過該對象實現UIViewControllerAnimatedTransitioning中的代理方法.
協議: UIViewControllerAnimatedTransitioning
協議方法: 1.  public   func  transitionDuration(transitionContext:  UIViewControllerContextTransitioning ?) ->  NSTimeInterval  (功能: 返回動畫時長)
2.  public   func  animateTransition(transitionContext:  UIViewControllerContextTransitioning )  (功能: 控制器的呈現和關閉都會掉用此方法)
3.  optional   public   func  animationEnded(transitionCompleted:  Bool )  (功能: 動畫結束時調用此方法)
分析: 該協議的方法傳入了一個新的東西: transitionContext , 轉場上下文, 裡面存放著有關轉場動畫的所有數據.
運用: 1. 通過  transitionContext. viewForKey ( UITransitionContextToViewKey )! 可以拿到需要呈現的控制器的view
2. 通過  transitionContext. viewForKey ( UITransitionContextFromViewKey )! 可以拿到需要發起控制器的view
3. 通過拿到的控制器的view, 在 public   func  animateTransition(transitionContext:  UIViewControllerContextTransitioning ) 方法中判斷控制器的呈現和關閉來實現動畫.

2. func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning?
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
作用:返回一個遵守UIViewControllerAnimatedTransitioning協議的對象, 設置在控制器關閉的時候通過該對象實現UIViewControllerAnimatedTransitioning中的代理方法.
3.func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


好了,基本上通過以上的操作, 就可以完成自定義的轉場動畫了. 真的感覺不費吹灰之力.

这篇关于Swit轉場動畫的簡單分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/976008

相关文章

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Spring中Bean有关NullPointerException异常的原因分析

《Spring中Bean有关NullPointerException异常的原因分析》在Spring中使用@Autowired注解注入的bean不能在静态上下文中访问,否则会导致NullPointerE... 目录Spring中Bean有关NullPointerException异常的原因问题描述解决方案总结

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

python-nmap实现python利用nmap进行扫描分析

《python-nmap实现python利用nmap进行扫描分析》Nmap是一个非常用的网络/端口扫描工具,如果想将nmap集成进你的工具里,可以使用python-nmap这个python库,它提供了... 目录前言python-nmap的基本使用PortScanner扫描PortScannerAsync异

Oracle数据库执行计划的查看与分析技巧

《Oracle数据库执行计划的查看与分析技巧》在Oracle数据库中,执行计划能够帮助我们深入了解SQL语句在数据库内部的执行细节,进而优化查询性能、提升系统效率,执行计划是Oracle数据库优化器为... 目录一、什么是执行计划二、查看执行计划的方法(一)使用 EXPLAIN PLAN 命令(二)通过 S

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置