回歸初心 —— iOS 之原生 Frame 布局

前言: 不知道從何時(shí)起,F(xiàn)rame 布局開始漸漸淡出 iOS 開發(fā)的舞臺,越來越的多的小伙伴開始使用 xib、storyboard、swiftUI 及第三方 SDK 來進(jìn)行布局。然而,F(xiàn)rame 布局始終是我心目中的 iOS 布局之王。

BY:一位不愿透露姓名的靚仔

iOS 布局的前世今生:

1.原始:Frame

iOS 開發(fā)中最古老、最簡陋的布局方式,由開發(fā)人員手動(dòng)設(shè)置各個(gè)視圖的原點(diǎn)(origin)及大?。╯ize)從而確定整個(gè)視圖在父視圖的位置。

在最初的 iOS 開發(fā)中,由于針對機(jī)型有限,適配簡單,這種古老的布局方式顯得游刃有余。然而在資本主義利益熏心的驅(qū)使下,千奇百怪的 iOS 設(shè)備不斷進(jìn)入人們的日常生活,程序猿們不得不一一適配這些新設(shè)備,漸漸地, Frame 布局顯得越來越力不從心,革命的聲音就此出現(xiàn)……

2. 拋磚引玉:AutoLayout

在 Apple 賺得盆滿缽滿之后,終于沒忘記體恤一下其生態(tài)圈的各位工程師,為我們在 iOS6 中帶來了新的局部方案:Autolayout,此套方案核心為“參照”及“約束”,開發(fā)人員只需要從這兩個(gè)角度將視圖的呈現(xiàn)方式使用代碼描述出來,后續(xù)的工作即可交給系統(tǒng)自動(dòng)處理。

然而理想都是豐滿的,現(xiàn)實(shí)總是殘酷的,AutoLayout 提供的 API 過于冗長,而要將視圖的“參照”及“約束”描述清楚,需要從多個(gè)維度調(diào)用多條 API 才能達(dá)到,而且 AutoLayout 的脾氣也不太好,一旦缺少必要的”參照“或者”約束“,就可能會(huì)導(dǎo)致整個(gè)程序掛掉,此時(shí)的 Autolayout,更像是一個(gè)半成品,沒幾個(gè)程序員愿意為它舉牌,大家寧愿繼續(xù)被 Frame 約束壓榨,也不愿意使用 Autolayout ……

3. 曙光:Masonry

Autolayout 無人問津,究其根源是因?yàn)槠?API 設(shè)計(jì)問題。但大家都明白,Autolayout 的核心思維正是解決 iOS 布局之痛的關(guān)鍵,此時(shí)陸續(xù)有第三方開始嘗試封裝對 Autolayout 進(jìn)行封裝,簡化其 API,提高易用性。 Masonry 在眾多第三方布局 SDK 中脫穎而出,其簡練的語法及函數(shù)式調(diào)用深得廣大開發(fā)者的青睞。

古人云:凡是都有其兩面性。autolayout 在 masonry 的光環(huán)加持下大行其道,成為 iOS 程序員對付 UI 布局問題的一道利劍,然而 autolayout 也有其先天弱勢 —— 。

Autolayout 的性能問題:

Autolayout 會(huì)將約束條件轉(zhuǎn)換成線性規(guī)劃問題,在通過 Cassowary 算法求解線性規(guī)劃問題得到 frame。對 autolayout 底層原理及?Cassowary 算法感興趣的同學(xué)可以自行 google,在這里講可能篇幅不夠??梢院唵蔚睦斫鉃?AutoLayout 在界面需要布局的時(shí)候會(huì)把我們設(shè)定好的約束條件轉(zhuǎn)換成 X 個(gè) N 元 N 次方程,然后扔給系統(tǒng),讓系統(tǒng)計(jì)算出最終視圖上各個(gè)元素的 frame,如果你對 N 元 N 次方程的求解復(fù)雜度還沒有個(gè)概念的話,可以嘗試自己寫一個(gè)程序來求解 N 元 N 次方程……

Autolayout Frame 性能分析

借用 Draveness 大佬的分析圖,可以看到 Autolayout 的性能明顯低于 Frame 布局,所謂出來混的總要還的,我們在代碼上偷的懶,在性能上可一分都沒少還(遮臉哭)。我們知道當(dāng)渲染時(shí)間大于1/60秒(16.67毫秒)時(shí),程序即會(huì)出現(xiàn)肉眼可察覺的卡頓。上圖中,F(xiàn)rame 布局可以保持在500個(gè) View 同時(shí)渲染時(shí)間低于16毫秒,而使用 autolayout 時(shí),僅僅 100 個(gè) view 的渲染時(shí)間就達(dá)到了 55.11 毫秒。

回歸初心:

我做了7年 iOS 開發(fā),我寫了7年 Frame 布局。對我來說,F(xiàn)rame 布局有其獨(dú)有的魅力與吸引力,我喜歡把視圖中每個(gè)元素掌握在自己手中的感覺,喜歡在使用 Frame 布局時(shí),每個(gè)元素隨著代碼在我腦海中逐漸拼接成整個(gè)視圖的感覺。

也許你會(huì)認(rèn)為這是我的偏激與頑固,在實(shí)際工作中,我也使用 xib, storyboard,使用 autolayout 和 masonry,學(xué)習(xí)并汲取其精華將其應(yīng)用到 Frame 布局中。既然我們可以為 autolayout 封裝 SDK 提高其 API 的易用性,那為什么不能封裝最原始的 Frame 布局來提高其通用性呢?這樣既可以優(yōu)雅的使用 Frame 布局,又可以得到最佳的新能表現(xiàn)。

現(xiàn)在我使用一套自己不斷改進(jìn)后的 Frame 布局方式,在 API 簡潔度、易用性、代碼復(fù)雜度上我都認(rèn)為比目前的第三方布局用起來更加得心應(yīng)手。

讓我們使用一個(gè)稍微復(fù)雜一點(diǎn)的界面看看我現(xiàn)在如何使用 Frame 布局,在屏幕控制器中央顯示一個(gè)搶購信息,涉及到了多個(gè)子視圖的布局:

布局示例-豎屏
布局示例-橫屏
我的布局代碼

界面一共13個(gè)元素,以上布局代碼共14行,就目前來說比其他任何一種布局方式更加簡短明了,目前這套布局方案在 Frame 的基礎(chǔ)上,大量使用了 autolayout 中 ”參照“ 和 ”約束“ 等思維,將核心思路集中在視圖與視圖的空間關(guān)系上,并使用鏈?zhǔn)秸{(diào)用最大程度減少冗余代碼并保持清晰的代碼可讀性。

由于布局中均使用相對關(guān)系,所以無論在任何尺寸手機(jī)上或者屏幕改變旋轉(zhuǎn)方向,均可以正常布局。而在上述代碼運(yùn)行完畢之后,所有視圖的 frame 信息均已計(jì)算完成,系統(tǒng)沒有額外的計(jì)算負(fù)擔(dān)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容