UI佈局
界面佈局常見的幾種方式
- xib佈局;
- storyboard佈局;
- 純代碼佈局--frame;
- 純代碼佈局--Autolayout;
xib佈局
· xib文件實際也是一個xml文件,也就是xml的可視化文件,解析xml節點,在通過runtime動態轉換。
· xib佈局也分爲兩個階段,一個是iphone6之前的小屏佈局,以width:320px的橫向座標爲基礎的autoresizing佈局,一個是iphone6之後的Autolayout佈局。
· 由於寬度限制在320px,所以除了高度,沒有其他適配問題,佈局較爲簡單,主要是以frame和autoresizing的結合。
· 自動佈局的出現,使得界面佈局不在侷限於frame等比例適配機制,可以通過子視圖於父視圖直接的約束,或者是同級視圖直接的約束來實現相對佈局,靈活性更強。
storyboard佈局
· storyboard是建立在xib的基礎上,可以把整個APP的交互用一個或者多個模塊的storyboard拼接起來,顯得更加直觀,優點是快捷、直觀,缺點是:耦合性較強、佈局改動不靈活。
純代碼佈局--frame
· frame佈局顧名思義,主要是以座標計算的形式來實現視圖的佈局,一般都做法是define設定一個屏幕scale比例值,對標750px的2倍屏寬度,從而計算出視圖的frame(x, y, width, height)
純代碼佈局--Autolayout
· 官方提供的Autolayout-API,主要是通過生成多個NSLayoutConstraint的集合,賦予其對應的View,來實現對View的約束(注意:View必須開啓Autolayout屬性且superView已經addSubview該View)。缺點:使用官方提供的API實現Autolayout代碼會比較臃腫。
· 使用Masonry實現Autolayout佈局,Masonry的API是使用鏈式編程的形式,簡單易懂;相對官方提供的API,使用便捷,可讀性較強。
純代碼佈局--frame與Autolayout的對比
· 隨着iphone的更新換代,市面上的iphone手機屏幕尺寸各式各樣,如果APP不實現橫豎屏切換,frame佈局和Autolayout都是可以實現基本的UI效果;
· frame佈局相對傳統一些,需要根據參照屏幕(6s尺寸)來實現比例縮放,計算起來會比較麻煩;autoLayout則相對流行一些,只要確保約束成立,就可以實現佈局的定位,特別是搭配Masonry的使用,是現在比較通用的一種UI佈局方式;
· 在動畫實現上,frame佈局和AutoLayout佈局也是不一樣的,前者是通過設置frame、錨點、position等位置尺寸屬性來實現動畫效果,後者則是通過修改約束來實現動畫效果;
當然,兩者也是可以一起使用的,具體也可以根據UI效果來做選擇。
UI渲染
View的構成與層級關係
· 每個View都包含一個Layer,向一個View添加subView,也類似把subView的layer添加到View中,UIView還提供了繪圖API:drawRect,可以在該方法中獲取圖形上下文,並實現圖形的繪製,調用setNeedsDisplay刷新繪製;
· 添加到View的subView會在mainRunloop觸發後進行繪製,並回調layoutSubviews方法,subView佈局發生變化時,也是在mainRunloop觸發後進行繪製,並回調layoutSubviews方法,layoutSubviews方法只有在多個操作在不同mainRunloop的觸發時間段纔會多次回調。
備註:圖層的嵌套越多,加載速度越慢,過度嵌套會影響整個頁面的流暢性。特別是比較複雜的圖文混排list,快速地滑動會出現明顯的頓挫感,解決方案是把結構複雜的多個圖層通過圖形上下文的形式轉化爲單圖層渲染。
View的渲染
· 上面提到View的本質layer,每個layer都有個content這個content指向的是一塊緩存又名baking store;Objective-c提供了Core Animation的渲染內核,底層是由OpenGL實現GPU渲染,流程大致如下:
- 初始化用於繪製的上下文EAGLContext;
- 創建幀緩衝區和渲染緩衝區,設置畫布的寬高;
- 添加附件,比如顏色附件或者深度附件;
- 切換到幀緩衝區,在幀緩衝中進行繪製;
- 切換到屏幕緩衝區,讀取幀緩衝中的信息;
- 繪製到屏幕上,在容器dealloc時刪除緩衝區。
GPU的離屏渲染
On-Screen Rendering:當前屏幕渲染,指的是GPU的渲染操作在當前用於顯示的屏幕緩衝區進行。
Off-Screen Rendering:離屏渲染,指的是GPU在當前屏幕緩衝區外新開闢一個緩衝區進行渲染操作。
· 離屏渲染主要開銷:創建新的緩衝區、屏幕緩衝區到離屏緩衝區的來回切換。
· IOS中主要是由於layer的某些屬性設置導致的離屏渲染,常見的有遮罩(mask)、裁切(clip)、透明(opaque)、陰影(shadow)、柵格化(rasterize)、圓角(cornerRadius),離屏渲染會讓APP的交互變得不流暢(如:比較複雜的圖文混排list),所以應該儘量避免使用,採用其他方式來實現。
渲染性能優化
· 使用FaceBook的AsyncDisplayKit來寫複雜的界面,能夠獲得異步繪製,預先加載等諸多好處。
· YYKit圖文混排引擎,大多數性能要求較高的界面就是圖文混排,比如微博Feed,微信朋友圈等界面。
· 異步繪製,把複雜的界面,放到後臺線程裏繪製成一個bitmap,然後再顯示。雖然有些延遲,不過換來的卻是平滑的界面。
· 儘量使用CALayer,因爲Layer是一個輕量級的視圖結構,它不接受通知,不接受觸摸,不在響應鏈。所以,相對於UIView來說,它的性能較好。並且CALayer及其子類是可以使用GPU渲染的,能夠硬件加速。
· 預加載與緩存,對於複雜的TableView,可以對Cell視圖的各個控件的大小,位置後臺進行預計算,並且緩存起來。這樣保證在heightForRow和cellForRow中不進行大量的計算。
· 圖片的處理,儘量使用成熟的庫,比如SDWebImage等,能夠在後臺進行圖片解碼,減少CPU的使用。儘量不要變形圖片,保證圖片與view尺寸一致。