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

相关文章

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

找不到Anaconda prompt终端的原因分析及解决方案

《找不到Anacondaprompt终端的原因分析及解决方案》因为anaconda还没有初始化,在安装anaconda的过程中,有一行是否要添加anaconda到菜单目录中,由于没有勾选,导致没有菜... 目录问题原因问http://www.chinasem.cn题解决安装了 Anaconda 却找不到 An

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

C++ 各种map特点对比分析

《C++各种map特点对比分析》文章比较了C++中不同类型的map(如std::map,std::unordered_map,std::multimap,std::unordered_multima... 目录特点比较C++ 示例代码 ​​​​​​代码解释特点比较1. std::map底层实现:基于红黑

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

Spring 中 BeanFactoryPostProcessor 的作用和示例源码分析

《Spring中BeanFactoryPostProcessor的作用和示例源码分析》Spring的BeanFactoryPostProcessor是容器初始化的扩展接口,允许在Bean实例化前... 目录一、概览1. 核心定位2. 核心功能详解3. 关键特性二、Spring 内置的 BeanFactory

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

MyBatis-Plus中静态工具Db的多种用法及实例分析

《MyBatis-Plus中静态工具Db的多种用法及实例分析》本文将详细讲解MyBatis-Plus中静态工具Db的各种用法,并结合具体案例进行演示和说明,具有很好的参考价值,希望对大家有所帮助,如有... 目录MyBATis-Plus中静态工具Db的多种用法及实例案例背景使用静态工具Db进行数据库操作插入

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C