上一篇文章學習到了基礎的 SwiftUI 相關 UI 元件的知識,讓我們可以建造出簡單的 App 頁面,但是如果要呈現出市面上商業 App 漂亮的頁面,那肯定沒有這麼簡單,我們需要深度理解 View 跟 Modifiers 能夠為我們做到什麼事情,那麼就繼續往下看吧!
struct ContentView: View {
var body: some View {
Text("Hello, SwiftUI!")
.foregroundColor(.blue)
}
}
當我們建立基本的 View 結構則是會如上面的程式碼一樣,我們定義了一個叫做 ContentView,裡面則是 Text 顯示文字以及 .foregroundColor(.blue) 設定會讓文字顯示藍色,而 .foregroundColor(.blue) 就是 Modifier,它協助我們修改了 Text 的外觀
struct DynamicView: View {
@State private var isToggled = false
var body: some View {
Toggle(isOn: $isToggled) {
Text("切換")
}
if isToggled {
Text("顯示的文本")
}
}
}
可以把 View 封裝成一個 DynamicView ,如上程式碼是製作可以拖拉切換的 Toggle,依賴 isToggled 決定顯示的文本是否顯示,讓它更能重複使用於各個畫面
如果發現有三個一樣的 Text ,它們都擁有一樣設定的外觀,那程式碼就會重複寫三次,為了精簡程式碼,我們就可以特別把它抽出來客製化
struct CustomModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.foregroundColor(.white)
.background(Color.blue)
.cornerRadius(10)
}
}
在這裡我們則是會繼承 ViewModifier ,跟之前繼承 View 寫法不一樣, fun body 裡面做的事情就是統一這個 Modifier 拿到 content 時會固定設定的外觀,範例程式碼是把前景顏色設定為白色,背景藍色,圓角 10
但光是這樣封裝還不太夠,只有這樣變成我們程式碼在調用的時候會變成下面的程式碼
Text("顯示的文本").modifier(CustomModifier())
但是這樣的寫法不太好看,跟原本其他的 Modifier 寫法不夠一致
extension View {
func customStyle() -> some View {
self.modifier(CustomModifier())
}
}
因此讓 View 多加了一個 extension 去拓展新的 function,把客製化的 Modifier 封裝在裡面
Text("文本")
.customStyle()
.font(.title)
.padding()
最後我們在建立 Text 的時候就能直接使用我們客製化的 Modifier,利用 .customStyle() 去調用,而且還可以繼續疊加原本就有的 Modifier,像是 padding() 和 .font(.title),這樣就獲得了一致的寫法,也更簡潔了
假設我們對我們客製化的 Modifier 需要設定 Color 值,則寫法不是改 func body 的 input 參數,而是在 struct 裏面宣告一個變數 color
struct MyColorModifier: ViewModifier {
var color: Color
func body(content: Content) -> some View {
content
.environment(\.myColor, color)
}
}
而要調用時,則會變成如下程式碼,這段寫法就比較特別,變數可以直接變成建構子塞入的值
extension ChildView {
func myColor(_ color: Color) {
self.modifier(MyColorModifier(color: color)
}
}
參考來自SwiftUI ViewModifier for custom View
宣告式 UI 的寫法都十分相似,連 Android 的 Jetpack Compose 也是有 Modifier,所以如果想學其他平台的宣告式 UI ,當概念通了之後,就很容易在各個平台穿梭,這點跟非宣告式 UI 時框架的學習成本相對來說降低了很多,總之我們在使用 SwiftUI 是離不開 View 和 Modifier,如果有興趣也可以看如下網站可以讀得更詳細