談談iOS中的View和動畫
做iOS開發也有一段時間了,幾乎每天都得和各種各樣的View打交道,熟練使用View是做好iOS的基本功,正所謂知其然跟要知其所以然,所以今天就來學習視圖到底是怎么工作的。
渲染機制
這張圖是蘋果官方 Core Animation 里面的截圖、可以看出渲染視圖的流程是
GPU -> OpenGL / Core Graphics -> CA -> UIKit/AppKit
詳細的過程如圖:

1、設置Layer的屬性. frame, alpha, backgroundColor等
2、創建backing image: 無論是通過setContents將一個image傳給layer,還是通過 drawRect 或 drawLayer:inContext 畫出來的, drawRect: 等函數在這個階段被調用
3、準備工作: CA準備渲染layer各種屬性數據,準備傳遞給render server. 同時解壓渲染的image. (除了 imageName: 方法從bundle加載的image會立刻解壓之外,其他的比如直接從硬盤讀入,或者網上下載的image不會立刻解壓,在真正渲染的時候才解壓)
4、提交:CA打包layer信息及動畫參數,通過IPC(進程間通信)傳遞給render server。
5、數據到達render server后,會被反序列化成render tree。然后render server會根據layer屬性,用OpenGL準備渲染
6、渲染到屏幕。
上面這些內容參考來自 這里 ,里面有更詳細的解釋。對性能優化有非常大的幫助。
交互方式
這是蘋果官方文檔里面的一個截圖,解釋了視圖的工作原理,如何去響應事件。
- UIKit把事件打包成 UIEvent 對象,并分發到相對應的視圖。
- 在事件回調的代碼里可以處理視圖的相關問題。
- 改變視圖或者子類屬性(frame, bounds, alpha)
- 調用 setNeedsLayout 方法更新視圖布局
- 調用 setNeedsDisplay 或者 setNeedsDisplayInRect: 方法重繪視圖
- 通知控制器改變數據
- 如果視圖有幾何上的改變,UIKit會根據下面的規則來更新子視圖:
- 如果使用了 Autoresizing ,則會根據這些規則來調整視圖
- 如果實現了layoutSubView方法,則UIKit會調用它。
- 任何已經更新了的視圖會和已可見的視圖混合一起,提交給圖形硬件去顯示。
- 渲染到屏幕上。
UIView和CALayer關系
CALayer 是QuartzCore庫內的類。是iOS基本的繪制單元。 UIView是CALayer的上層封裝,增加了事件的處理。UIView里面好多屬性都是和CALayer里面一一對應的。
UIView好比一個容器,用來管理視圖,顯示視圖、處理事件;CALayer則著重視圖的繪制
更詳細的資料可以參考 這里
Offscreen Render(離屏渲染)
1、有些效果不能直接會知道屏幕上,必須先會知道一個offscreen的image contentext上,這種操作會引入而外的內存和CPU消耗。( rounded corners , layer masks , drop shadows , layer rasterization )
2、實現了 drawRect 或者 drawLayer:inContext ,為了支持任意的繪制, Core Graphic 會創建一個大小跟需要畫得view一樣的backing image。并且畫完后傳輸到render渲染。
更詳細的資料可以參考 這里
參考資料
來自: http://www.liuchendi.com/2016/01/11/iOS/32_TalkAboutView/