在 SwiftUI 官方教程中,Apple 時(shí)常提出“化整為零”的界面布局思想。簡(jiǎn)單來(lái)說(shuō),Apple 推薦 SwiftUI 視圖的構(gòu)建方式是:用若干自定義小視圖來(lái)構(gòu)成上層的功能視圖。
這是為什么呢?
在本篇博文中,我們將用一個(gè)通俗易懂的示例來(lái)討論這樣做的重要原因。
無(wú)需等待,Let’s Go!
首先,從軟件工程的角度來(lái)說(shuō),用自定義視圖來(lái)代替原始布局代碼有利于封裝和代碼重用。
比如 SwiftUI 中需要在各個(gè)功能視圖頂部彈出 HUD 小視圖:
如果在每個(gè)功能視圖中都寫(xiě)一遍 HUD 視圖代碼,之后一旦需要修改 HUD 實(shí)現(xiàn),在所有父視圖中都需做出改動(dòng),這種“牽一發(fā)而動(dòng)全身”的行為顯然不符合日后的代碼維護(hù)。
所以,這時(shí)把 HUD 的實(shí)現(xiàn)放在定制視圖中無(wú)疑是一個(gè)明智的選擇:
struct HUD: View {@ViewBuilder let content: Content
var body: some View {content
.padding(.horizontal, 12)
.padding(16)
.background(
Capsule()
.foregroundColor(Color.white)
.shadow(color: Color(.black).opacity(0.16), radius: 12, x: 0, y: 5)
)
}
}
現(xiàn)在,在所有功能視圖中我們都可以嵌入統(tǒng)一的 HUD 子視圖,避免了代碼重復(fù):
1.2 自定義視圖有利于 SwiftUI 優(yōu)化界面刷新SwiftUI 非常聰明,當(dāng)視圖對(duì)應(yīng)的狀態(tài)發(fā)生變化時(shí),它會(huì)及時(shí)的刷新?tīng)顟B(tài)對(duì)應(yīng)的內(nèi)容。
不過(guò)在有些情況下, SwiftUI 仍然需要我們來(lái)為它提供“更優(yōu)化”的刷新建議。
具體來(lái)說(shuō):如果一個(gè)狀態(tài)對(duì)應(yīng)的視圖界面被刷新,其中所有的視圖都會(huì)被刷新,盡管其中某些視圖實(shí)際上無(wú)需刷新(繞口令?)。
這時(shí),若我們用自定義子視圖分割顯示邏輯代碼,且被更改的狀態(tài)沒(méi)有影響到該子視圖,則 SwiftUI 就不會(huì)刷新這些子視圖,從而有效的提高了視圖渲染性能。
有些童鞋可能擔(dān)心 SwiftUI 中將父視圖劃分為大量自定義子視圖會(huì)帶來(lái)顯示性能上的災(zāi)難。
其實(shí)這種擔(dān)心是多慮了。
首先,SwiftUI 中視圖的實(shí)現(xiàn)非常輕量級(jí),而且 Apple 對(duì) SwiftUI 中整個(gè)視圖繼承體系的渲染在底層做了很好的優(yōu)化,嵌入大量子視圖一般不會(huì)顯著影響顯示性能。其次,如果確實(shí)有性能問(wèn)題,我們隨時(shí)可以通過(guò)性能檢測(cè)工具來(lái)確定性能瓶頸點(diǎn),再選擇優(yōu)化也不遲。
過(guò)早優(yōu)化是“萬(wàn)惡之源”,切記切記!😉
2. 一個(gè)“栗子”也許大家對(duì)上面 “自定義視圖有利于 SwiftUI 優(yōu)化界面刷新” 這一概念仍不是太理解。
沒(méi)關(guān)系,下面我們就用一個(gè)簡(jiǎn)單的例子讓小伙伴們直觀(guān)感受界面刷新優(yōu)化前后的差別。
extension ShapeStyle where Self == Color {static var random: Color {Color(
red: .random(in: 0...1),
green: .random(in: 0...1),
blue: .random(in: 0...1)
)
}
}
struct HyButtonStyle: ButtonStyle {func makeBody(configuration: Configuration) ->some View {configuration.label
.font(.title)
.padding()
.foregroundColor(.white)
.background(Color.gray)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}
struct ContentView: View {@State var s_one = 0
@State var s_two = 0
var body: some View {NavigationStack {VStack(spacing: 50.0) {Text("one: \(s_one)")
HStack {Text("two: \(s_two)")
}
.padding()
.background(Color.random)
HStack(spacing: 50) {Button("add one"){s_one += 1
}.buttonStyle(HyButtonStyle())
Button("add two"){s_two += 1
}.buttonStyle(HyButtonStyle())
}
}
.font(.title2)
.padding()
.background(Color.random)
.navigationTitle("視圖“冗余”刷新演示")
}
}
}
順面說(shuō)一下,上述代碼利用了
SwiftUI 如何快速識(shí)別視圖(View)界面的刷新是由哪個(gè)狀態(tài)的改變導(dǎo)致的? 博文中的調(diào)試技術(shù)。
簡(jiǎn)單來(lái)說(shuō),當(dāng)視圖被刷新時(shí)其背景色也會(huì)發(fā)生變化,我們可以用肉眼輕易辨別出每個(gè)視圖是否被刷新了。
上面是一段非常簡(jiǎn)單的代碼,按道理來(lái)說(shuō),狀態(tài) s_one 只會(huì)影響父視圖中的 Text("one: ") 文本,而 s_two 只會(huì)影響 Text("two: ") 文本。但實(shí)際上它們會(huì)互相影響:
如上圖所示:改變 s_one 會(huì)刷新 Text("two: "),而改變 s_two 同樣也會(huì)強(qiáng)制不相干 Text("one: ") 視圖的刷新(觀(guān)察它們背景色的變化)。
下面,我們將 Text("two: ") 包裝到自定義的子視圖 HySubView 中去:
struct HySubView: View {@Binding var val: Int
var body: some View {HStack {Text("s_two: \(val)")
}
.padding()
.background(Color.random)
}
}
將 ContentView 中原內(nèi)容替換為 HySubView:
VStack(spacing: 50.0) {Text("one: \(s_one)")
HySubView(val: $s_two)
// 其它代碼從略...
}
現(xiàn)在,我們?cè)賮?lái)看看更改 s_one 和 s_two 狀態(tài)對(duì)它們的影響:
可以看到,現(xiàn)在 s_one 和 s_two 狀態(tài)的變化只會(huì)影響其對(duì)應(yīng)的視圖,而不會(huì)影響到無(wú)關(guān)的視圖了。于是乎我們利用自定義子視圖避免了無(wú)必要的“冗余”刷新操作。
這只是一個(gè)非常簡(jiǎn)單的例子,在包含大量狀態(tài)的復(fù)雜界面中,利用自定義子視圖無(wú)疑會(huì)帶來(lái)可觀(guān)的界面渲染性能提升!棒棒噠!💯🚀
總結(jié)在本篇博文里,我們討論了 SwiftUI 中利用子視圖代替父視圖界面布局內(nèi)容的重要優(yōu)勢(shì),并為大家舉了一個(gè)非常通俗易懂的例子。
那么,感謝觀(guān)賞,再會(huì)!😎
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
本文名稱(chēng):SwiftUI中為什么應(yīng)該經(jīng)常用子視圖替換父視圖中的大段內(nèi)容?-創(chuàng)新互聯(lián)
網(wǎng)站URL:http://jinyejixie.com/article30/cshiso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷(xiāo)、虛擬主機(jī)、企業(yè)建站、App設(shè)計(jì)、網(wǎng)站建設(shè)、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容