SwiftUI - 前導(dǎo)篇

前言

在學(xué)習(xí)了前端js及跨平臺(tái)語言開發(fā)Flutter之后,發(fā)現(xiàn)學(xué)習(xí)SwiftUI很簡單,布局方式很容易里理解,代碼也很容易上手,在Swift語言的基礎(chǔ)上,可以理解為 SwiftUI 就是?種描述式的構(gòu)建 UI 的?式。代碼簡潔,編碼容易上手,未來前途無量,xdm學(xué)起來!?。?br> 本篇文章稍顯枯燥,如果沒時(shí)間或不想閱讀的,可以直接略過,嘻嘻嘻...

SwiftUI定義

2019年WWDC大會(huì)上,蘋果在壓軸環(huán)節(jié)向大眾宣布了基于Swift語言構(gòu)建的全新UI框架——SwiftUI,開發(fā)者可通過它快速為所有的Apple平臺(tái)創(chuàng)建美觀、動(dòng)態(tài)的應(yīng)用程序。
SwiftUI在iOS13、macOS10.15、tvOS13和watchOS6上運(yùn)行。而且SwiftUI的運(yùn)行速度優(yōu)于UIKit,他減少了界面的層次結(jié)構(gòu),因此減少了繪制步驟,并且他完全繞過了CoreAnimation,直接進(jìn)入Metal。
SwiftUI是一個(gè)用戶界面開發(fā)工具包,它讓我們使用聲明式(declarative)編程的方式設(shè)計(jì)應(yīng)用。這是一種很酷的說法,他的意思其實(shí)就是:我們需要告訴SwiftUI,我們的UI應(yīng)該長成什么樣子;當(dāng)用戶和它互動(dòng)(interact)的時(shí)候,我們的UI應(yīng)該如何反應(yīng)。
SwiftUI 作為 Apple 在自家平臺(tái)使用 Swift 語言打造的首個(gè)重量級(jí)系統(tǒng)框架,將為這個(gè)平臺(tái)上用戶界面的構(gòu)建方式帶來革命性的轉(zhuǎn)變。它摒棄了從上世紀(jì)八十年代開始就一直被使用的指令式 (imperative) 編程的方式,轉(zhuǎn)而向投聲明式 (declarative) 編程的陣營,這提高了我們解決問題時(shí)所需要著手的層級(jí),從而讓我們可以將更多的注意力集中到更重要的創(chuàng)意方面。

關(guān)于SwiftUI的推廣

在 SwiftUI 出現(xiàn)之前,蘋果不同的設(shè)備之前的開發(fā)框架并不互通,移動(dòng)端的?程師和桌?端的?程師需要掌握的知識(shí),有很??部分是差異化的。比如iOS、macOS、WatchOS,這種碎片化的開發(fā)體驗(yàn)無疑會(huì)大大增加開發(fā)者所需消耗的時(shí)間精力,也不利于構(gòu)建跨平臺(tái)的軟件體驗(yàn)。蘋果希望直接優(yōu)化語言本身,并統(tǒng)一所有設(shè)備的開發(fā)體驗(yàn),讓開發(fā)者更容易上手,也更容易將心里的想法轉(zhuǎn)化為運(yùn)行的程序。
除了統(tǒng)一終端以外,蘋果也在想方設(shè)法增加開發(fā)者的數(shù)量,提升單個(gè)應(yīng)用質(zhì)量。方式也非常符合第一性思維原則——降低開發(fā)的難度。所以先有了 Swift,緊接著又推出了 SwiftUI,基本就可以看做蘋果在推廣新語言的過程中一個(gè)里程碑式的節(jié)點(diǎn)。

SwiftUI特點(diǎn)

1.界面布局簡便

在 UIKit 框架中,由于坐標(biāo)系統(tǒng)的存在,界面上的每一個(gè)元素都需要開發(fā)者進(jìn)行布置,有時(shí)候計(jì)算量會(huì)非常大也非常繁瑣,例如長寬的改變或是屏幕可視面積的變化等。這種線性的方式被稱為指令式 (imperative)編程。以一行文字為例,放置在哪個(gè)坐標(biāo)、寬度多少、在哪里換行、怎么斷句、字形字號(hào)是多少、最終高度多少、是否需要縮小字號(hào)來完全顯示等,這些都是開發(fā)者在制作界面時(shí)要考慮和計(jì)算妥當(dāng)?shù)膯栴}。到了新設(shè)備發(fā)布,用戶可能會(huì)換更大屏幕的手機(jī),系統(tǒng)支持動(dòng)態(tài)字體調(diào)節(jié)等新功能,此時(shí)原先的程序不進(jìn)行適配就可能出現(xiàn)顯示問題,開發(fā)者就需要回頭進(jìn)行程序的重新調(diào)試。
換做 SwiftUI之后,上述的很多變量就被系統(tǒng)接管了,也取消了坐標(biāo)系統(tǒng),開發(fā)者要做的就是直觀的告訴系統(tǒng)放置一個(gè)圖像,上面加一行文字,右邊加一個(gè)按鈕。系統(tǒng)會(huì)根據(jù)屏幕大小、方向等自動(dòng)渲染這個(gè)界面,開發(fā)者也不再需要像素級(jí)的進(jìn)行計(jì)算。這被稱為聲明式 (declarative) 編程。

2.鏈?zhǔn)秸{(diào)用修改屬性

鏈?zhǔn)秸{(diào)用是 Swift 語言的一種特性,就是用來使用函數(shù)方法的一種方式??梢韵矜湕l那樣不斷地調(diào)用函數(shù),中間不需要斷開。使用這種方式可以大大減少代碼量。
除了系統(tǒng)提供的屬性可以使用之外,開發(fā)者也可以進(jìn)行自定義。例如將不同字體、字號(hào)、行間距、顏色等屬性統(tǒng)合起來,可以組合成為一個(gè)叫「標(biāo)題」的文字屬性。之后凡是需要將某一行文字設(shè)置成標(biāo)題,直接添加這個(gè)自定義的屬性即可,使用這種方式進(jìn)行開發(fā)無疑能夠極大的避免無意義的重復(fù)工作,更快的搭建應(yīng)用界面框架。

3.界面元素組件化

理論上來講,每一個(gè)復(fù)雜的視圖,都是由大量簡單的單元視圖構(gòu)成。但是函數(shù)方法可以包裝起來,做到僅在有需要的時(shí)候進(jìn)行調(diào)取使用。在 UIKit 框架下的頁面元素解耦卻不太容易,一般都是針對(duì)某種特定情境,很難進(jìn)行移植。有時(shí)候可能手機(jī)橫屏就會(huì)讓頁面元素混亂,就更別論頁面元素的組件化了。
不過 SwiftUI 在布局上的特點(diǎn),卻可以便捷的拆分復(fù)雜的視圖組件。單一的組件不僅可以自由組合,而且在蘋果的任意平臺(tái)上都可以使用該組件,達(dá)到跨平臺(tái)的實(shí)現(xiàn)。
一般我個(gè)人會(huì)將視圖組件區(qū)分為基礎(chǔ)組件、布局組件功能組件。因?yàn)?SwiftUI 的界面不再像 UIKit 那樣,用 ViewController 承載各種 UIView 控件,而是一切都是視圖。這種視圖的拼裝方式提高了界面開發(fā)的靈活性和復(fù)用性。

4.與UIKit彼此相容

一般開發(fā)者學(xué)習(xí)新技術(shù)有一個(gè)最大的障礙就是原先的項(xiàng)目怎么辦?但 SwiftUI 在這一點(diǎn)上考慮得非常周到。由于是一個(gè)新發(fā)布的框架,UI 組件并不齊全,當(dāng) SwiftUI 中并沒有提供類似的功能時(shí),就可以把 UIKit 中已有的部分進(jìn)行封裝,提供給 SwiftUI 使用。開發(fā)者需要做的僅僅是遵循UIViewRepresentable協(xié)議即可。相反,在已有的項(xiàng)目中,也可以僅用 SwiftUI 制作一部分的 UI 界面。
當(dāng)然兩種代碼的風(fēng)格是截然不同的,但在使用上卻基本沒有性能的損失。在最終的運(yùn)行效果上,用戶也無法分辨出兩種界面框架的不同。

5.單一數(shù)據(jù)源

一直以來復(fù)雜的UI結(jié)構(gòu)都會(huì)創(chuàng)造更為復(fù)雜的數(shù)據(jù)和邏輯管理需求,每次在用戶交互,或是數(shù)據(jù)來源發(fā)生變化的時(shí)候,能否及時(shí)更新相關(guān)界面組件,不然就會(huì)引起顯示問題。
但是在 SwiftUI 中,只要在屬性聲明時(shí)加上 @State 等關(guān)鍵詞,就可以將該屬性和界面元素聯(lián)系起來,在每次數(shù)據(jù)改動(dòng)后,都有機(jī)會(huì)決定是否更新視圖。這樣就可以將所有的屬性都集中到一起進(jìn)行管理和計(jì)算,也不再需要手寫刷新的邏輯。因?yàn)樵?SwiftUI 中,頁面渲染前會(huì)將開發(fā)者描述的界面狀態(tài)儲(chǔ)存為結(jié)構(gòu)體,更新界面就是將之前狀態(tài)的結(jié)構(gòu)體銷毀,然后生成新的狀態(tài)。而在繪制界面的過程中,會(huì)自動(dòng)比較視圖中各個(gè)屬性是否有變化,如果發(fā)生變化,便會(huì)更新對(duì)應(yīng)的視圖,避免全局繪制和資源浪費(fèi)。(看到這里,突然想到Flutter的渲染更新機(jī)制,只渲染改變的部分,優(yōu)化性能,單走一個(gè)6
使用這種方式,讀和寫都集中在一處,開發(fā)者就能夠更好地設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),比較方便的增減類型和排查問題。而不用再考慮線程、原子狀態(tài)、尋找最新數(shù)據(jù)等各種細(xì)節(jié),再?zèng)Q定通知相關(guān)的界面進(jìn)行刷新。

6.設(shè)計(jì)工具&快速預(yù)覽

Xcode 包含直觀的設(shè)計(jì)工具,只需拖放操作就能使用 SwiftUI 輕松構(gòu)建界面。當(dāng)您在設(shè)計(jì)畫布中操作時(shí),您的每一項(xiàng)編輯都會(huì)與相鄰編輯器中的代碼保持完全同步。在您鍵入時(shí)代碼會(huì)立即以預(yù)覽形式顯示,您對(duì)預(yù)覽進(jìn)行的任何更改會(huì)立即反映在您的代碼中。Xcode 會(huì)即時(shí)重新編譯您的更改,并將它們插入到 app 的運(yùn)行版本中,方便您隨時(shí)查看和編輯。
SwiftUI可與Xcode11以及上無縫協(xié)作,讓代碼和設(shè)計(jì)完美同步,同時(shí)還提供對(duì)動(dòng)態(tài)類型暗黑模式、本地化可訪問性的自動(dòng)支持。

拖放操作。只需在畫布上拖放控件,就能調(diào)整組件在用戶界面中的位置。點(diǎn)按打開檢查器,即可選擇字體、顏色、對(duì)齊方式和其他設(shè)計(jì)選項(xiàng),并可通過光標(biāo)輕松重新排列控件。多數(shù)這些可視化編輯器也可在代碼編輯器中使用,因此您可以使用檢查器來探索各個(gè)控件的新修飾符,即使您偏好手動(dòng)編寫界面組件代碼也沒問題。您還可以將控件從資源庫拖放到設(shè)計(jì)畫布上,或者直接拖放到代碼中。
預(yù)覽。您現(xiàn)在可以為任何 SwiftUI 視圖創(chuàng)建一個(gè)或多個(gè)預(yù)覽來獲取樣本數(shù)據(jù)。用戶能看見的任何內(nèi)容 (例如大字體、本地化深色模式),你幾乎都能配置。預(yù)覽也可以顯示您的 UI 在任何設(shè)備和方向上的呈現(xiàn)效果。

SwiftUI布局方式

SwiftUI采用前端開發(fā)中流行的彈性布局,可以說繼承了彈性布局的大部分優(yōu)點(diǎn),并且也是聲明式的語法。我們只需聲明用戶界面應(yīng)具備的功能便可。例如,你可以寫明你需要一個(gè)由文本欄組成的項(xiàng)目列表,然后描述各個(gè)欄位的對(duì)齊方式、字體和顏色。你的代碼比以往更加簡單直觀和易于理解,可以節(jié)省你的時(shí)間和維護(hù)工作。
在學(xué)習(xí)了Flutter之后,SwiftUI的布局方式是真的和Flutter布局如出一轍,所以代碼上面上手操作比較快,再者Swift語言的掌握,興趣越來越濃厚。

響應(yīng)式編程框架 Combine

在構(gòu)建復(fù)雜界面的過程中,數(shù)據(jù)的流通一直是指令式編程中相當(dāng)讓人頭疼的部分。
在 UIKit 框架下時(shí),會(huì)配合 Target-Action或者 protocol-delegate 模式來交換信息,使用Key-Value Observing (KVO) 或者 Key-Value Coding (KVC) 來監(jiān)測(cè)變化和讀寫屬性。但即便開發(fā)者熟練地使用這些工具,面對(duì)日益增長的應(yīng)用復(fù)雜性,掉坑里的可能性還是非常大。因?yàn)橛刑嘈枰_發(fā)者妥善處理的數(shù)據(jù)流動(dòng),例如數(shù)據(jù)改動(dòng)后需要通知相關(guān)的頁面進(jìn)行刷新,或是讓關(guān)聯(lián)數(shù)據(jù)重新計(jì)算等。

像是 React Native 和 Flutter 這樣的移動(dòng)端跨平臺(tái)方案,由于采用了聲明式 UI 的編寫方式和嚴(yán)格的數(shù)據(jù)流動(dòng)方向,就能夠大幅減輕開發(fā)者的思考負(fù)擔(dān)。

SwiftUI 很明顯也吸收了這些現(xiàn)代的編程思想,在另一個(gè)重量級(jí)系統(tǒng)框架 Combine 的協(xié)助下,實(shí)現(xiàn)了單一數(shù)據(jù)源的管理。

響應(yīng)式編程的核心是將所有事件轉(zhuǎn)化成為異步的數(shù)據(jù)流,這剛好就是 Combine 的主要功能。Combine 采用觀察者模式,對(duì)應(yīng)多個(gè)觀察者,可以分別訂閱感興趣的內(nèi)容。在 SwiftUI 的界面布局過程中,不同的 View 就是觀察者,分別訂閱了相關(guān)聯(lián)的屬性,并在數(shù)據(jù)發(fā)生變化之后就能夠自動(dòng)的重新渲染。

SwiftUI動(dòng)畫

在 SwiftUI 中,做動(dòng)畫變的十分簡單。Apple 的教程里提供了兩種動(dòng)畫的方式:
1、直接在 View 上使用 .animation modifier
2、使用 withAnimation { }來控制某個(gè) State,進(jìn)而觸發(fā)動(dòng)畫。

對(duì)于只需要對(duì)單個(gè) View 做動(dòng)畫的時(shí)候,animation(_:)要更方便一些,它和其他各類 modifier 并沒有太大不同,返回的是一個(gè)包裝了對(duì)象 View 和對(duì)應(yīng)的動(dòng)畫類型的新的 View。animation(_:) 接受的參數(shù) Animation 并不是直接定義 View 上的動(dòng)畫的數(shù)值內(nèi)容的,它是描述的是動(dòng)畫所使用的時(shí)間曲線,動(dòng)畫的延遲等這些和 View 無關(guān)的東西。具體和 View 有關(guān)的,想要進(jìn)行動(dòng)畫的數(shù)值方面的變更,由其他的諸如 rotationEffectscaleEffect這樣的 modifier 來描述。

能看到這里的童鞋,說明很有耐心嘛,??,接下來我們就真正開始我們的SwiftUI之旅吧,go go go !!!

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

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

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