本文主要認(rèn)識(shí)SwiftUI脸秽,并且學(xué)會(huì)如何使用SwiftUI。
主要內(nèi)容:
- 什么是SwiftUI
- 創(chuàng)建的第一個(gè)SwiftUI工程
- SwiftUI的簡(jiǎn)單使用
1. 什么是SwiftUI
2019年WWDC大會(huì)上蝴乔,蘋(píng)果在壓軸環(huán)節(jié)向大眾宣布了基于Swift語(yǔ)言構(gòu)建的全新UI框架——SwiftUI记餐,開(kāi)發(fā)者可通過(guò)它快速為所有的Apple平臺(tái)創(chuàng)建美觀、動(dòng)態(tài)的應(yīng)用程序薇正。
SwiftUI的運(yùn)行速度優(yōu)于UIKit片酝,他減少了界面的層次結(jié)構(gòu),因此可以減少繪制步驟挖腰,并且他完全繞過(guò)了CoreAnimation雕沿,直接進(jìn)入Metal,可以有優(yōu)秀的渲染性能猴仑。
1.1 認(rèn)識(shí)
SwiftUI is a user interface toolkit that lets us design apps in a declarative way.
SwiftUI 就是?種聲明式的構(gòu)建界面的用戶(hù)接口工具包审轮。
SwiftUI使用聲明式的語(yǔ)法構(gòu)建UI,我們只需要向系統(tǒng)聲明UI的View樣式辽俗,以及View如何轉(zhuǎn)換狀態(tài)疾渣,其他的過(guò)程都交給系統(tǒng)去處理。
聲明式語(yǔ)法和指令式語(yǔ)法的區(qū)別:
- 聲明式的我們需要提前聲明好每個(gè)view的各種狀態(tài)崖飘,以及狀態(tài)轉(zhuǎn)變的條件榴捡。后續(xù)界面和用戶(hù)在互動(dòng)時(shí),系統(tǒng)會(huì)幫我們自動(dòng)進(jìn)行狀態(tài)切換朱浴。
- 指令式的我們需要給每個(gè)view先設(shè)置好默認(rèn)狀態(tài)吊圾,后續(xù)界面和用戶(hù)在互動(dòng)時(shí),需要通過(guò)指令不停的去轉(zhuǎn)變view的狀態(tài)
- 因此聲明式的UI是提前聲明好各種狀態(tài)赊琳,系統(tǒng)會(huì)自動(dòng)幫我們進(jìn)行狀態(tài)切換街夭。指令式的UI是通過(guò)我們?cè)O(shè)定的指令來(lái)轉(zhuǎn)換狀態(tài)
- 比如界面調(diào)整、用戶(hù)交互躏筏、機(jī)型適配板丽,UIKit都需要手動(dòng)調(diào)整view,對(duì)于SwiftUI我們只需要聲明好我們想要的樣式,系統(tǒng)會(huì)幫我們?nèi)フ{(diào)整view埃碱。
- 可以這么說(shuō)猖辫,SwiftUI相比于UIKit更加的抽象化了
1.2 優(yōu)點(diǎn)
- 統(tǒng)一蘋(píng)果終端
- 在 SwiftUI 出現(xiàn)之前,蘋(píng)果不同的設(shè)備之前的開(kāi)發(fā)框架并不互通砚殿,增加開(kāi)發(fā)者所需消耗的時(shí)間精力啃憎,也不利于構(gòu)建跨平臺(tái)的軟件體驗(yàn)
- SwiftUI具有了跨平臺(tái)性,蘋(píng)果的平臺(tái)都可以使用似炎,iOS辛萍、macOS、tvOS羡藐、watchOS
- 降低界面開(kāi)發(fā)難度
- UIKit 的基本思想要求ViewController 承擔(dān)絕?部分職責(zé)贩毕,它需要協(xié)調(diào) model,view 以及??交互仆嗦。這帶來(lái)了巨?的sideeffect 以及?量的狀態(tài)
- SwiftUI是聲明式的構(gòu)建方式辉阶,我們只需要聲明好界面系統(tǒng)會(huì)自動(dòng)轉(zhuǎn)換狀態(tài),搭建界面更加的簡(jiǎn)單
- 更加高效
- 默認(rèn)使用Metal渲染瘩扼,性能非常高,比UIKit要好
- 更扁平化的內(nèi)聯(lián)數(shù)據(jù)結(jié)構(gòu)去分配內(nèi)存谆甜,值類(lèi)型。占用內(nèi)存很少(所以在輕應(yīng)用的開(kāi)發(fā)更適合使用SwiftUI)
- 代碼量相比UIKit要更少集绰,效率更高
- 更好的配合Swift語(yǔ)言
- SwiftUI 使用了大量 Swift 的語(yǔ)言特性
1.3 特點(diǎn)
- 聲明式語(yǔ)法
- 與UIKit布局相比规辱,更加的抽象化,只需要向系統(tǒng)聲明界面樣式以及樣式變化條件倒慧,其他的系統(tǒng)會(huì)幫我們實(shí)現(xiàn)按摘,不需要我們自己去調(diào)整視圖
- 鏈?zhǔn)秸{(diào)用屬性
- 鏈?zhǔn)秸{(diào)用是 Swift 語(yǔ)言的一種特性,就是使用函數(shù)式編程纫谅,可以像鏈條那樣不斷地調(diào)用函數(shù)炫贤,中間不需要斷開(kāi)。使用這種方式可以大大減少代碼量付秕。
- 除了系統(tǒng)提供的屬性可以使用之外兰珍,開(kāi)發(fā)者也可以進(jìn)行自定義
- 例如將不同字體、字號(hào)询吴、行間距掠河、顏色等屬性統(tǒng)合起來(lái),可以組合成為一個(gè)叫「標(biāo)題」的文字屬性猛计。之后凡是需要將某一行文字設(shè)置成標(biāo)題唠摹,直接添加這個(gè)自定義的屬性即可,使用這種方式進(jìn)行開(kāi)發(fā)無(wú)疑能夠極大的避免無(wú)意義的重復(fù)工作奉瘤,更快的搭建應(yīng)用界面框架勾拉。
- 界面元素的組件化
- UIKit耦合了很多的操作邏輯煮甥,很難進(jìn)行移植,更遑論組件化了
- 而SwiftUI僅僅聲明界面樣式藕赞,所以是可以將復(fù)雜視圖的拆分出來(lái)組件化
- 甚至還可以在其他平臺(tái)使用成肘,以此跨平臺(tái)
- 一般我個(gè)人會(huì)將視圖組件區(qū)分為基礎(chǔ)組件、布局組件和功能組件
- 與UIKit互相兼容
- 把 UIKit 中已有的部分進(jìn)行封裝斧蜕,提供給 SwiftUI 使用双霍。開(kāi)發(fā)者需要做的僅僅是遵循UIViewRepresentable協(xié)議即可
- 并且在已有的項(xiàng)目中,也可以?xún)H用 SwiftUI 制作一部分的 UI 界面
- 兩種代碼的風(fēng)格是截然不同的批销,但在使用上卻基本沒(méi)有性能的損失洒闸。在最終的運(yùn)行效果上,用戶(hù)也無(wú)法分辨出兩種界面框架的不同均芽。
-
真實(shí)數(shù)據(jù)源(Source of truth)(重點(diǎn))
- SwiftUI中的數(shù)據(jù)源一定會(huì)是真實(shí)的顷蟀,也就是準(zhǔn)確的
- 在OC中,一個(gè)view的狀態(tài)由多種因素導(dǎo)致的骡技,不同的來(lái)源,不同的邏輯操作(因此需要考慮及時(shí)更新界面)
- 因此在Swift中羞反,提供了單一數(shù)據(jù)源的說(shuō)法
- 只要在屬性聲明時(shí)加上 @State 等關(guān)鍵詞布朦,就可以將該屬性和界面元素聯(lián)系起來(lái),在每次數(shù)據(jù)改動(dòng)后昼窗,都有機(jī)會(huì)決定是否更新視圖是趴。
- 系統(tǒng)將所有的屬性都集中到一起進(jìn)行管理和計(jì)算,也不再需要手寫(xiě)刷新的邏輯澄惊。
- 因?yàn)樵?SwiftUI 中唆途,頁(yè)面渲染前會(huì)將開(kāi)發(fā)者描述的界面狀態(tài)儲(chǔ)存為結(jié)構(gòu)體,更新界面就是將之前狀態(tài)的結(jié)構(gòu)體銷(xiāo)毀掸驱,然后生成新的狀態(tài)肛搬。
- 而在繪制界面的過(guò)程中,會(huì)自動(dòng)比較視圖中各個(gè)屬性是否有變化毕贼,如果發(fā)生變化温赔,便會(huì)更新對(duì)應(yīng)的視圖,避免全局繪制和資源浪費(fèi)鬼癣。
- 使用這種方式陶贼,讀和寫(xiě)都集中在一處,開(kāi)發(fā)者就能夠更好地設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)待秃,比較方便的增減類(lèi)型和排查問(wèn)題拜秧。而不用再考慮線(xiàn)程、原子狀態(tài)章郁、尋找最新數(shù)據(jù)等各種細(xì)節(jié)枉氮,再?zèng)Q定通知相關(guān)的界面進(jìn)行刷新。
- 設(shè)計(jì)工具和快速預(yù)覽功能
- Xcode 包含直觀的設(shè)計(jì)工具,只需拖放操作就能使用 SwiftUI 輕松構(gòu)建界面嘲恍。
- 拖放操作
- 動(dòng)態(tài)替換
- 預(yù)覽
1.4 SwiftUI和UIKit的區(qū)別
- SwiftUI是描述式的(聲明式的)足画,UIKit是指令式的
- UIKit的View都是一個(gè)Class,SwiftUI的View是Struct
- Swift的View不需要像UIKit那樣操作邏輯控制佃牛,只負(fù)責(zé)展示
- 因?yàn)榻Y(jié)構(gòu)體比類(lèi)更簡(jiǎn)單更輕量淹辞,創(chuàng)建幾乎沒(méi)有開(kāi)銷(xiāo)
- Swift的運(yùn)行速度要優(yōu)于UIKit
- Swift的開(kāi)發(fā)難度要低于UIKit
2. 創(chuàng)建的第一個(gè)SwiftUI工程
2.1 創(chuàng)建SwiftUI工程
創(chuàng)建過(guò)程和之前一樣,只不過(guò)這里要選擇Swift語(yǔ)言和SwiftUI
查看界面如下:
2.2 SwiftUIAPP代碼解析
代碼:
import SwiftUI
@main
struct TodoSwiftUIApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
說(shuō)明:
- 這個(gè)結(jié)構(gòu)體就是一個(gè)APP俘侠,繼承自APP
- 定義了一個(gè)body屬性象缀,拿到APP的窗口
- 這里調(diào)用ContentView就是我們定義的View
- 所以這里就是拿到我們創(chuàng)建的APP的UI
2.3 ContentView結(jié)構(gòu)體解析
代碼:
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, world!") .padding()
}
}
說(shuō)明:
- 結(jié)構(gòu)體ContentView定義了屏幕的UI,遵守View協(xié)議
- 所有在SwiftUI中顯示的元素都需要遵守View協(xié)議
- 因此爷速,必須聲明一個(gè)叫做body的屬性央星,這個(gè)body可以返回整理好的View,詳情可以看博客Swift基礎(chǔ)語(yǔ)法(十一)泛型
- some是不透明類(lèi)型惫东,不透明在于不知道返回的具體類(lèi)型是什么莉给,只知道遵守View協(xié)議
- 當(dāng)前body內(nèi)只包含了一個(gè)Text視圖,文本視圖是圖形化的廉沮,顯示一行或多行只讀文本的視圖颓遏,也就是說(shuō)他是一個(gè)文本標(biāo)簽(先簡(jiǎn)單的看做是OC中的Label,后續(xù)文章會(huì)詳細(xì)介紹SwiftUI中的View)
2.4 預(yù)覽認(rèn)識(shí)
代碼:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
說(shuō)明:
- UI的預(yù)覽結(jié)構(gòu)體滞时,遵守PreviewProvider協(xié)議
- 定義了一個(gè)previews變量叁幢。它拿到的也是ContentView(),即UI
- 它可以修改我們的預(yù)覽屬性
比如我們想要在iPhone SE上進(jìn)行預(yù)覽坪稽,需要進(jìn)行如下操作:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(). previewDevice("iPhone SE (2nd generation)")
}
}
通過(guò)這種方式就可以查看不同機(jī)型下的預(yù)覽
預(yù)覽畫(huà)面查看
說(shuō)明:
- 可以在這里選擇打開(kāi)或關(guān)閉預(yù)覽界面
- 在預(yù)覽設(shè)置中曼玩,共有六項(xiàng)
- Preview是刷新視圖
- 運(yùn)行預(yù)覽
- 發(fā)快遞
- 切換橫豎屏
- 設(shè)置預(yù)覽配置
- 新增預(yù)覽界面
- 預(yù)覽配置
- 調(diào)節(jié)預(yù)覽尺寸
3. SwiftUI的簡(jiǎn)單使用
代碼:
struct ContentView: View {
var body: some View {
VStack(alignment: .center, spacing: 20){
Text("Hello")
.foregroundColor(.red)
Button(action:{
print("button tapped")
}){
Text("Press Me")
}
.foregroundColor(.green)
}
}
}
說(shuō)明:
- 所有視圖代碼都放在body中
- VStack是進(jìn)行垂直布局,alignment表示對(duì)齊方式,這里是居中對(duì)齊窒百,還有spacing表示內(nèi)間距黍判,為20
- Text是文本視圖
- Button是按鈕,action是點(diǎn)擊后的操作篙梢,Text("Press Me")是按鈕文本
- foregroundColor是Modeifiers样悟,后續(xù)會(huì)詳細(xì)講解
結(jié)果: