SwiftUI教程(一)SwiftUI的認(rèn)識(shí)

SwiftUI教程系列文章匯總

本文主要認(rèn)識(shí)SwiftUI脸秽,并且學(xué)會(huì)如何使用SwiftUI。

主要內(nèi)容:

  1. 什么是SwiftUI
  2. 創(chuàng)建的第一個(gè)SwiftUI工程
  3. 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ū)別:

  1. 聲明式的我們需要提前聲明好每個(gè)view的各種狀態(tài)崖飘,以及狀態(tài)轉(zhuǎn)變的條件榴捡。后續(xù)界面和用戶(hù)在互動(dòng)時(shí),系統(tǒng)會(huì)幫我們自動(dòng)進(jìn)行狀態(tài)切換朱浴。
  2. 指令式的我們需要給每個(gè)view先設(shè)置好默認(rèn)狀態(tài)吊圾,后續(xù)界面和用戶(hù)在互動(dòng)時(shí),需要通過(guò)指令不停的去轉(zhuǎn)變view的狀態(tài)
  3. 因此聲明式的UI是提前聲明好各種狀態(tài)赊琳,系統(tǒng)會(huì)自動(dòng)幫我們進(jìn)行狀態(tài)切換街夭。指令式的UI是通過(guò)我們?cè)O(shè)定的指令來(lái)轉(zhuǎn)換狀態(tài)
  4. 比如界面調(diào)整、用戶(hù)交互躏筏、機(jī)型適配板丽,UIKit都需要手動(dòng)調(diào)整view,對(duì)于SwiftUI我們只需要聲明好我們想要的樣式,系統(tǒng)會(huì)幫我們?nèi)フ{(diào)整view埃碱。
  5. 可以這么說(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)

  1. 聲明式語(yǔ)法
    1. 與UIKit布局相比规辱,更加的抽象化,只需要向系統(tǒng)聲明界面樣式以及樣式變化條件倒慧,其他的系統(tǒng)會(huì)幫我們實(shí)現(xiàn)按摘,不需要我們自己去調(diào)整視圖
  2. 鏈?zhǔn)秸{(diào)用屬性
    1. 鏈?zhǔn)秸{(diào)用是 Swift 語(yǔ)言的一種特性,就是使用函數(shù)式編程纫谅,可以像鏈條那樣不斷地調(diào)用函數(shù)炫贤,中間不需要斷開(kāi)。使用這種方式可以大大減少代碼量付秕。
    2. 除了系統(tǒng)提供的屬性可以使用之外兰珍,開(kāi)發(fā)者也可以進(jìn)行自定義
    3. 例如將不同字體、字號(hào)询吴、行間距掠河、顏色等屬性統(tǒng)合起來(lái),可以組合成為一個(gè)叫「標(biāo)題」的文字屬性猛计。之后凡是需要將某一行文字設(shè)置成標(biāo)題唠摹,直接添加這個(gè)自定義的屬性即可,使用這種方式進(jìn)行開(kāi)發(fā)無(wú)疑能夠極大的避免無(wú)意義的重復(fù)工作奉瘤,更快的搭建應(yīng)用界面框架勾拉。
  3. 界面元素的組件化
    1. UIKit耦合了很多的操作邏輯煮甥,很難進(jìn)行移植,更遑論組件化了
    2. 而SwiftUI僅僅聲明界面樣式藕赞,所以是可以將復(fù)雜視圖的拆分出來(lái)組件化
    3. 甚至還可以在其他平臺(tái)使用成肘,以此跨平臺(tái)
    4. 一般我個(gè)人會(huì)將視圖組件區(qū)分為基礎(chǔ)組件、布局組件和功能組件
  4. 與UIKit互相兼容
    1. 把 UIKit 中已有的部分進(jìn)行封裝斧蜕,提供給 SwiftUI 使用双霍。開(kāi)發(fā)者需要做的僅僅是遵循UIViewRepresentable協(xié)議即可
    2. 并且在已有的項(xiàng)目中,也可以?xún)H用 SwiftUI 制作一部分的 UI 界面
    3. 兩種代碼的風(fēng)格是截然不同的批销,但在使用上卻基本沒(méi)有性能的損失洒闸。在最終的運(yùn)行效果上,用戶(hù)也無(wú)法分辨出兩種界面框架的不同均芽。
  5. 真實(shí)數(shù)據(jù)源(Source of truth)(重點(diǎn))
    1. SwiftUI中的數(shù)據(jù)源一定會(huì)是真實(shí)的顷蟀,也就是準(zhǔn)確的
    2. 在OC中,一個(gè)view的狀態(tài)由多種因素導(dǎo)致的骡技,不同的來(lái)源,不同的邏輯操作(因此需要考慮及時(shí)更新界面)
    3. 因此在Swift中羞反,提供了單一數(shù)據(jù)源的說(shuō)法
      1. 只要在屬性聲明時(shí)加上 @State 等關(guān)鍵詞布朦,就可以將該屬性和界面元素聯(lián)系起來(lái),在每次數(shù)據(jù)改動(dòng)后昼窗,都有機(jī)會(huì)決定是否更新視圖是趴。
      2. 系統(tǒng)將所有的屬性都集中到一起進(jìn)行管理和計(jì)算,也不再需要手寫(xiě)刷新的邏輯澄惊。
      3. 因?yàn)樵?SwiftUI 中唆途,頁(yè)面渲染前會(huì)將開(kāi)發(fā)者描述的界面狀態(tài)儲(chǔ)存為結(jié)構(gòu)體,更新界面就是將之前狀態(tài)的結(jié)構(gòu)體銷(xiāo)毀掸驱,然后生成新的狀態(tài)肛搬。
      4. 而在繪制界面的過(guò)程中,會(huì)自動(dòng)比較視圖中各個(gè)屬性是否有變化毕贼,如果發(fā)生變化温赔,便會(huì)更新對(duì)應(yīng)的視圖,避免全局繪制和資源浪費(fèi)鬼癣。
    4. 使用這種方式陶贼,讀和寫(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)行刷新。
  6. 設(shè)計(jì)工具和快速預(yù)覽功能
    1. Xcode 包含直觀的設(shè)計(jì)工具,只需拖放操作就能使用 SwiftUI 輕松構(gòu)建界面嘲恍。
    2. 拖放操作
    3. 動(dòng)態(tài)替換
    4. 預(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

創(chuàng)建工程

查看界面如下:


UI界面

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ō)明:

  1. 結(jié)構(gòu)體ContentView定義了屏幕的UI,遵守View協(xié)議
  2. 所有在SwiftUI中顯示的元素都需要遵守View協(xié)議
  3. 因此爷速,必須聲明一個(gè)叫做body的屬性央星,這個(gè)body可以返回整理好的View,詳情可以看博客Swift基礎(chǔ)語(yǔ)法(十一)泛型
  4. some是不透明類(lèi)型惫东,不透明在于不知道返回的具體類(lèi)型是什么莉给,只知道遵守View協(xié)議
  5. 當(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ō)明:

  1. UI的預(yù)覽結(jié)構(gòu)體滞时,遵守PreviewProvider協(xié)議
  2. 定義了一個(gè)previews變量叁幢。它拿到的也是ContentView(),即UI
  3. 它可以修改我們的預(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à)面查看

預(yù)覽畫(huà)面

說(shuō)明:

  1. 可以在這里選擇打開(kāi)或關(guān)閉預(yù)覽界面
  2. 在預(yù)覽設(shè)置中曼玩,共有六項(xiàng)
    1. Preview是刷新視圖
    2. 運(yùn)行預(yù)覽
    3. 發(fā)快遞
    4. 切換橫豎屏
    5. 設(shè)置預(yù)覽配置
    6. 新增預(yù)覽界面
  3. 預(yù)覽配置
  4. 調(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ō)明:

  1. 所有視圖代碼都放在body中
  2. VStack是進(jìn)行垂直布局,alignment表示對(duì)齊方式,這里是居中對(duì)齊窒百,還有spacing表示內(nèi)間距黍判,為20
  3. Text是文本視圖
  4. Button是按鈕,action是點(diǎn)擊后的操作篙梢,Text("Press Me")是按鈕文本
  5. foregroundColor是Modeifiers样悟,后續(xù)會(huì)詳細(xì)講解

結(jié)果:

結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市庭猩,隨后出現(xiàn)的幾起案子窟她,更是在濱河造成了極大的恐慌,老刑警劉巖蔼水,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件震糖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡趴腋,警方通過(guò)查閱死者的電腦和手機(jī)吊说,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)论咏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人颁井,你說(shuō)我怎么就攤上這事厅贪。” “怎么了雅宾?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵养涮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我眉抬,道長(zhǎng)贯吓,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任蜀变,我火速辦了婚禮悄谐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘库北。我一直安慰自己爬舰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布寒瓦。 她就那樣靜靜地躺著洼专,像睡著了一般婉弹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嚣潜,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天站故,我揣著相機(jī)與錄音,去河邊找鬼旁舰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的恤筛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼芹橡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毒坛!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起林说,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤煎殷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后腿箩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體豪直,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年珠移,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弓乙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片末融。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖暇韧,靈堂內(nèi)的尸體忽然破棺而出勾习,到底是詐尸還是另有隱情,我是刑警寧澤懈玻,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布巧婶,位于F島的核電站,受9級(jí)特大地震影響酪刀,放射性物質(zhì)發(fā)生泄漏粹舵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一骂倘、第九天 我趴在偏房一處隱蔽的房頂上張望眼滤。 院中可真熱鬧,春花似錦历涝、人聲如沸诅需。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)堰塌。三九已至,卻和暖如春分衫,著一層夾襖步出監(jiān)牢的瞬間场刑,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工蚪战, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留牵现,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓邀桑,卻偏偏與公主長(zhǎng)得像瞎疼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子壁畸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容