SwiftUI 內的 API 方法:Self._printChanges()
SwiftUI 提供了一個僅用於除錯 (debugging) 的好方法,讓我們區分是什麼改動讓視圖重新加載。這個方法是用來查找錯誤的。當我們看到視圖在重新調用 body 屬性 (property),卻又不知道原因的時候,這個方法就大派用場了。
struct PrintingChanges: View {
@State var counter = 0
var body: some View {
Self._printChanges()
return Button {
counter += 1
} label: {
Text("Current Value \(counter)")
}
}
}
以上的程式碼中有幾個重點:
- 因為
_printChanges()
是一個靜態方法 (Static Method),我們需要使用Self
。 - 我們需要在 body 屬性內呼叫
Self._printChanges()
,也就是說,我們需要在原本的視圖程式碼中,添加一個顯式 (explicit) return keyword。 - 在預設情況下,所有視圖都有
_printChanges()
- 所有從下橫線 (_) 開頭的函式和屬性都是 Private API 的一部分,因此我們不會看到任何相關文檔。
從以上例子可見,我們點擊按鈕後,如果在 Console 看到東西,就代表某個屬性發生了變化。也就是說,屬性的變化對 UI 有影響,所以 SwiftUI 在渲染 (render) 視圖。
在我們開發 App 的時候,我們會使用不同的屬性包裝器 (property wrapper),那會導致視圖多次呈現。而如果我們使用 Self._printChanges()
,就會印出多個視圖。雖然 Apple 說它們十分輕巧,但還是會降低 App 的效能。
重要事項
SwiftUI 只會在屬性有改變,需要重新評估 body 時渲染視圖。如果你在視圖中使用的狀態變數並不是用於 UI 的話,印出的結果就不會有視圖的改變,SwiftUI 也不會渲染那個屬性。
當我們利用 print()
印出 State
屬性時,SwiftUI 就會重新渲染視圖,因此我們可以使用 _printChanges()
而不是 print
。
記得要用 iOS 15 來構建你的 App,才可以用這個 API。
使用 Colored Background
當我們在螢幕上處理各種 UI 組件時,有時會非常混亂,不知道每個組件在堆疊 (stack) 中佔用了多少空間。
我們可以選擇某個元素,並在 review 中查看它佔用了多少空間。但這個方法有點麻煩,畢竟我們無法反覆查看它。
我利用了 “debug only background-color” 修飾符來解決這個問題,讓我可以看到視圖的顏色,並正確地作出更改。
extension View {
func debugOnlyModifier<T: View>(_ modifier: (Self) -> T) -> some View {
#if DEBUG
return modifier(self)
#else
return self
#endif
}
private var colors: [Color] {
[.blue, .yellow, .green, .red, .brown, .cyan, .gray, .indigo, .mint, .pink, .orange]
}
func debugOnlyBackground() -> some View {
debugOnlyModifier {
$0.background(Rectangle().foregroundColor(colors.randomElement()))
}
}
}
你也可以這樣使用這個修飾符:
struct BackgroundColorChange: View {
let gridItems = [GridItem(.flexible()), GridItem(.flexible(minimum: 20, maximum: 50)), GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible(minimum: 10, maximum: 20))]
var body: some View {
ScrollView {
LazyVGrid(columns: gridItems, spacing: 0) {
ForEach(0...100, id: \.self) {
Text("\($0)")
.padding()
.debugOnlyBackground()
}
}
}
}
}
希望這個方法可以讓你發現 App 的問題。如果你有其他除錯的好方法,請留言與我分享。另外,如果你對 SwiftUI 的技術有興奮,可以閱讀這篇文章。謝謝你的閱讀。