SwiftUI之深入解析如何创建和组合视图
生活随笔
收集整理的這篇文章主要介紹了
SwiftUI之深入解析如何创建和组合视图
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、創(chuàng)建項(xiàng)目并體驗(yàn)畫(huà)布
① 系統(tǒng)要求
- 創(chuàng)建 SwiftUI 項(xiàng)目工程,體驗(yàn)畫(huà)布、預(yù)覽模式和 SwiftUI 模板代碼;
- 要想在 Xcode 中預(yù)覽畫(huà)布中的視圖,或者與畫(huà)布中的視圖進(jìn)行交互,需要 Mac 系統(tǒng)版本號(hào)不低于 macOS Catalina 10.15。
② 步驟
- 打開(kāi) Xcode,在啟動(dòng)頁(yè)面點(diǎn)擊創(chuàng)建新工程,或者在菜單中選擇文件->新建->項(xiàng)目:
- 在項(xiàng)目模板選擇器中,選擇 iOS 作為項(xiàng)目平臺(tái),選項(xiàng)單視圖應(yīng)用(App)作為項(xiàng)目模板,并點(diǎn)擊下一步(Next):
- 輸入項(xiàng)目名稱(chēng) FirstSwiftUI,選擇 SwiftUI 作為用戶(hù)界面的創(chuàng)建方式,并點(diǎn)擊下一步 Next,在磁盤(pán)目錄下選擇一個(gè)位置用來(lái)存放新創(chuàng)建的工程項(xiàng)目:
- 工程創(chuàng)建好并打開(kāi)后,在文件導(dǎo)航器中,選擇 ContentView.swift 文件,可以瀏覽一下 SwiftUI 視圖的組成結(jié)構(gòu)。默認(rèn)情況下,SwiftUI 的視圖文件包含兩個(gè)結(jié)構(gòu)體 Struct:
-
- 第一個(gè)結(jié)構(gòu)體遵循 View 協(xié)議,描述視圖的內(nèi)容和布局;
-
- 第二個(gè)結(jié)構(gòu)體聲明為第一個(gè)視圖的預(yù)覽視圖。
- 在**畫(huà)布(Canvas)上,點(diǎn)擊恢復(fù)(Resume)**按鈕可以顯示預(yù)覽視圖,也可以使用快捷鍵 Command+Option+P(如果工程中沒(méi)有出現(xiàn)畫(huà)布 Canvas,可以選擇菜單:編輯器 Editor -> 編輯器和畫(huà)布 Canvas,打開(kāi)畫(huà)布進(jìn)行預(yù)覽):
- 在 body 屬性?xún)?nèi)部,修改文字 Hello, world! 為其它的不同的文字,當(dāng)在改變代碼的同時(shí),預(yù)覽視圖也會(huì)實(shí)時(shí)的更新對(duì)應(yīng)的內(nèi)容變化:
二、定制文本視圖 Text View
① 通過(guò)修改代碼來(lái)改變視圖的顯示樣式
- 可以通過(guò)修改代碼來(lái)改變一個(gè)視圖的顯示樣式,也可以通過(guò)檢查器獲取視圖可修改屬性,然后再寫(xiě)對(duì)應(yīng)的代碼改變樣式。在創(chuàng)建應(yīng)用的過(guò)程中,可以同時(shí)使用源碼編輯器、畫(huà)布或者檢查器,無(wú)論當(dāng)前使用的是哪一個(gè)工具編輯視圖,代碼會(huì)保持和這些編輯器展示的樣式一致:
② 使用檢查器來(lái)定制視圖的顯示樣式
- 在預(yù)覽視圖中,按下 Command 鍵的同時(shí)點(diǎn)擊控件,會(huì)彈出一個(gè)編輯彈層,然后選擇檢查器 Inspect, 編輯彈層顯示所有可以定制的視圖屬性,選中的控件不同,可以定制的屬性集合也不相同:
- 使用檢查器把文字更改為T(mén)urtle Rock,也就是在應(yīng)用中顯示的第一個(gè)地標(biāo)的名稱(chēng):
- 改變字體修改器為 Title,使用系統(tǒng)字體修飾文字,可以自動(dòng)按照用戶(hù)在設(shè)備中設(shè)置的字體偏好大小進(jìn)行調(diào)整。定制 SwiftUI 視圖所調(diào)用的方法被稱(chēng)為視圖修改器 Modifiers,修改器在原視圖的基礎(chǔ)上修改部分顯示樣式和屬性,返回一個(gè)新的視圖,這樣就可以讓多個(gè)修改器串連進(jìn)行,形成水平方向的鏈?zhǔn)秸{(diào)用,或者垂直方向的堆疊調(diào)用:
- 手動(dòng)在代碼中添加 foregroundColor(.green) 屬性修改器,就會(huì)把文字的顏色調(diào)整為綠色。代碼是決定視圖樣式的根本,當(dāng)我們使用檢查器來(lái)改變或移除一個(gè)屬性修改器時(shí),Xcode 也會(huì)在代碼編輯器中同步改變或移除對(duì)應(yīng)的修改器代碼:
- 在代碼編輯器中,按下 Command 的同時(shí)點(diǎn)擊 Text 單詞也可以屬性彈窗,從中選擇檢查器后,再點(diǎn)擊 Color 彈出菜單,選擇繼承 Inherited,讓文字的顏色恢復(fù)成原來(lái)的黑色:
- 當(dāng)我們移除 foregroundColor(.green) 時(shí),Xcode 會(huì)自動(dòng)更新代碼來(lái)反映視圖的實(shí)際顯示狀況:
三、使用棧來(lái)組合視圖
- 上文中創(chuàng)建了標(biāo)題視圖,接下來(lái)要添加一些文本視圖來(lái)描述地標(biāo)所在州及所在公園的名稱(chēng)等其它詳細(xì)信息:
- 創(chuàng)建 SwiftUI 視圖就是在 body 屬性中描述視圖的內(nèi)容、布局及行為,但 body 屬性只返回單個(gè)視圖,這時(shí)組合多個(gè)視圖時(shí)可以把它們放入一個(gè)棧中,通過(guò)水平、垂直、前后嵌套多個(gè)視圖完成視圖組合,做為一個(gè)整體在 body 屬性中返回。
- 現(xiàn)在使用一個(gè)垂直棧,把標(biāo)題放在包含公園詳情的水平棧的上方,在水平棧中,布局公園詳情相關(guān)的內(nèi)容,可以使用 Xcode 提供的結(jié)構(gòu)化布局來(lái)把視圖嵌套在容器視圖中。
- ① 按下 Command 鍵的同時(shí),點(diǎn)擊 Text 視圖的初始化代碼打開(kāi)結(jié)構(gòu)化編輯彈窗,然后選擇把控件嵌套在垂直棧中 Embed in VStack,在棧中添加 Text View 控件可以從組件中直接拖進(jìn)棧中完成:
- ② 點(diǎn)擊 Xcode 右上角的 + 號(hào),托動(dòng)一個(gè) Text 控件到指定位置,代碼立即就會(huì)在編輯器中補(bǔ)全;
- ③ 把 Text 視圖的占位文本修改為 Joshua Tree Nation Park,視圖會(huì)自動(dòng)調(diào)整位置布局;
- ④ 設(shè)置位置控件的字體為子標(biāo)題樣式:
- ⑤ 設(shè)置 VStack 初始化參數(shù)為左對(duì)齊內(nèi)部的子視圖,默認(rèn)情況下,棧會(huì)把內(nèi)部視圖在自己的主軸上居中對(duì)齊,并自動(dòng)計(jì)算各子視圖的間距。下一步要添加一個(gè) Text 控制用來(lái)描述公園的狀態(tài),它水平排列在位置信息的右邊;
- ⑥ 在畫(huà)布內(nèi),command 按下的同時(shí)點(diǎn)擊位置視圖,在彈出的菜單中選擇嵌入到水平棧中 Embed in HStack;
- ⑦ 在位置控件的后面加一個(gè)公園狀態(tài)的 Text 視圖,并把占位文字改為 California,字體設(shè)置為子標(biāo)題樣式;
- ⑧ 為了水平布局使用整個(gè)屏幕寬度,在位置控件和公園狀態(tài)控件中間添加一個(gè) Spacer 控件,用來(lái)填充兩個(gè)控件中間的空白部分,并把兩個(gè)控件分別頂向屏幕的兩側(cè);Spacer 是一個(gè)可以伸縮的空白控件,它負(fù)責(zé)占用其它控件布局完成后剩下的所有空間;
- ⑨ 使用 padding() 修改器給地標(biāo)信息內(nèi)容視圖整體加內(nèi)邊距;
四、創(chuàng)建自定義圖像視圖 Image
- 有了地標(biāo)名稱(chēng)、地標(biāo)位置及狀態(tài)視圖,下一步再添加一個(gè)地標(biāo)圖片視圖,這個(gè)圖片視圖將自定義遮罩 mask、邊框 border 和陰影 shadow;可以從控件加中拖一個(gè) Image 到畫(huà)布,或直接寫(xiě)代碼到代碼編輯器中。
- 在項(xiàng)目資源文件中找到 turtlerock.png 圖片,把它拖入資源編輯器 asset catalog editor 中,Xcode 會(huì)創(chuàng)建一個(gè)新的圖片集來(lái)存放這個(gè)圖片,然后創(chuàng)建一個(gè) SwiftUI 視圖:
- 選擇文件->新建->文件,打開(kāi)模板選擇器,在用戶(hù)界面(User Interface)板塊下,選擇 SwiftUI View 并點(diǎn)擊下一步,命名為 CircleImage.swift,并點(diǎn)擊創(chuàng)建(Create),現(xiàn)在已經(jīng)準(zhǔn)備好插入圖片并修改布局來(lái)滿(mǎn)足設(shè)計(jì)目標(biāo):
- 用 Image 替換 Text,并使用 turtlerock 圖片初始化 Image 視圖;
- 添加 clipShape(Circle()) 修改器到 Image,給圖片添加圓形剪切效果;Circle 是一個(gè)形狀,它可以被用作遮罩、也可以是圓圈,還可以是圓形填充視圖;
- 創(chuàng)建另一個(gè)灰色的圓圈并把它作為一個(gè)浮層添加到圖片上,相當(dāng)于給圖片加了一個(gè)灰色邊框;
- 給視圖添加半徑為 10 的陰影;
- 把圓形邊框的顏色改成白色,就完成了自定義圖片視圖的創(chuàng)建:
五、UIKit 視圖與 SwiftUI 視圖混合使用
- 現(xiàn)在要?jiǎng)?chuàng)建一個(gè)地圖視圖,可以使用 MapKit 中的 MKMapView 視圖類(lèi)來(lái)渲染地圖,要在 SwiftUI 中使用 UIView 及其子類(lèi),需要把這些 UIView 包裹在一個(gè)遵循 UIViewRepresentable 協(xié)議的 SwiftUI 視圖中,SwiftUI 中也包含適配 WatchKit 和 AppKit 的類(lèi)似的協(xié)議:
- 創(chuàng)建一個(gè)自定義視圖用來(lái)容納和顯示 MKMapView:
-
- 選擇文件->新建->文件,選擇 iOS 平臺(tái),選擇 SwiftUI View 模板,并點(diǎn)擊下一步(Next),命名文件為 MapView.swift,并點(diǎn)擊創(chuàng)建(Create);
-
- 代碼中導(dǎo)入 MapKit 引用,聲明 MapView 遵循 UIViewRepresentable 協(xié)議,UIViewRepresentable 協(xié)議要求實(shí)現(xiàn)兩個(gè)方法 UIView(context:) 和 updateUIView(_:context:),第一個(gè)方法用來(lái)創(chuàng)建 MKMapView,第二個(gè)方法用來(lái)配置視圖響應(yīng)狀態(tài)變化;
-
- 替換 body,用 makeUIView(context:) 方法來(lái)代替,創(chuàng)建并返回一個(gè)空的 MKMapView;
-
- 創(chuàng)建方法 updateUIView(_:context:),在方法內(nèi)部設(shè)置地圖視圖的坐標(biāo)為 Turle Rock 的中心。在靜態(tài)模式下預(yù)覽時(shí),只會(huì)渲染 SwiftUI 視圖的部分,因?yàn)?MKMapView 是 UIView 的子類(lèi),所以需要切換到實(shí)時(shí)預(yù)覽模式下才能看到地圖被完全渲染出來(lái);
-
- 點(diǎn)擊 Live Preview(實(shí)時(shí)預(yù)覽)按鈕,可能需要點(diǎn)擊 Try Again 和 Resume 按鈕來(lái)激活預(yù)覽模式的切換,切換到實(shí)時(shí)預(yù)覽模式下不久就可以看到指定地標(biāo)所在的地圖位置:
六、組合地標(biāo)詳情頁(yè)
- 我們已經(jīng)完成了創(chuàng)建一個(gè)地標(biāo)詳情頁(yè)所需要的各種子視圖元素:名稱(chēng)、地點(diǎn)、圓形圖片以及位置地圖,現(xiàn)在可以把這些視圖元素組合在一起形成地標(biāo)詳情頁(yè)的整個(gè)視圖:
- 在項(xiàng)目工程瀏覽器中選擇 ContentView.swift 文件;
- body 屬性中嵌入一個(gè) VStack 視圖,它內(nèi)部包含另一個(gè) VStack 視圖,內(nèi)部的 VStack 視圖又包含三個(gè) Text 視圖;
- 在外層 VStack 的頂部添加自定義的地圖視圖 MapView,并使用 frame(width:height:) 設(shè)置視圖大小。當(dāng)只指定高度時(shí),寬度會(huì)自動(dòng)計(jì)算為父視圖的寬度,在這里就是屏幕寬度;
- 點(diǎn)擊 Live Preview 按鈕進(jìn)入實(shí)時(shí)預(yù)覽模式,查看地圖渲染情況,在實(shí)時(shí)預(yù)覽模式下可以編輯視圖,最新的改動(dòng)也可以實(shí)時(shí)的刷新出來(lái);
- 在 MapView 后面再添加一個(gè) CircleImage 視圖;
- 為了讓圖片視圖疊放在地圖視圖的上面,可以設(shè)置圖片視圖的垂直偏移量為 -130,圖片視圖的底部?jī)?nèi)邊距也為 -130,這個(gè)效果就是把圖片垂直上移了 130,同時(shí)和下面的文字區(qū)域留出了 130 的空白分隔區(qū);
- 在外層 VStack 內(nèi)部的最下面加上 Spacer,可以讓上面的視圖內(nèi)容頂?shù)狡聊坏纳线?#xff1b;
- 為了讓地圖的視圖內(nèi)容顯示在狀態(tài)欄的下方,可以給 MapView 添加 edgesIgnoringSafeArea(.top) 修改器,這可
- 以讓它在布局時(shí)忽略頂部的安全區(qū)域邊距;
七、總結(jié)
- 在聲明自定義 SwiftUI 視圖時(shí),視圖布局要聲明 body 屬性中;View 協(xié)議中要求實(shí)現(xiàn) body 屬性,每一個(gè) SwiftUI 視圖都遵循 View 協(xié)議。
- 有如下代碼布局,那么運(yùn)行視圖效果是什么樣?
- 從 body 屬性中返回三個(gè)視圖:
- 修改器每次都是返回一個(gè)新的對(duì)象,所以多個(gè)修改器可以通過(guò)鏈?zhǔn)秸{(diào)用,配置視圖時(shí),使用修改器的方式如下:
- 完整示例:SwiftUI 之如何創(chuàng)建和組合視圖。
總結(jié)
以上是生活随笔為你收集整理的SwiftUI之深入解析如何创建和组合视图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SwiftUI之如何创建常量绑定与自定义
- 下一篇: SwiftUI之深入解析如何创建列表展示