View の body の中に Self._printChanges() を組み込むと、その View の再描画のトリガーとなった状態変数(@State 等)を出力してくれます。
想定外の再描画のきっかけがわからない時などのデバッグに役立つでしょう。
【SwiftUI 3.0】Self._printChanges で View の再描画を監視する
Self._printChanges() の使用例
Toggle ボタンと List を配置したサンプルです。
struct Todo: Identifiable, Hashable {
let id = UUID().uuidString
let title: String
let description: String
}
struct ContentView: View {
@State private var isOn = false
@State private var todos = [Todo]()
var body: some View {
let _ = Self._printChanges()
VStack {
Toggle(isOn ? "ONです" : "OFFです", isOn: $isOn)
List(todos, id: \.self) { todo in
VStack(alignment: .leading) {
Text(todo.title).font(.title2)
Text(todo.description)
}
}
}
.padding()
.task() {
fetchTodos()
}
}
func fetchTodos() {
todos = [
Todo(title: "やることその1", description: "やることその1の内容です。"),
Todo(title: "やることその2", description: "やることその2の内容です。"),
Todo(title: "やることその3", description: "やることその3の内容です。"),
Todo(title: "やることその4", description: "やることその4の内容です。"),
Todo(title: "やることその5", description: "やることその5の内容です。")
]
}
}
var body: some View の先頭で Self._printChanges をコールしています。
「let _ =」としているのはビルドエラーを回避するためです(body の中で戻り値 void の関数を呼べないため)。
var body: some View {
let _ = Self._printChanges()
上記のサンプルでは、初回の読み込み時の task 内で todos をセットするタイミングと、Toggle ボタンを ON/OFF する度にデバッグコンソールに出力されます。
「(対象のView名): _状態変数名 changed」という形式出力されていることがわかります。
@StateObject や @Published でも同じように出力してくれます。
注意点
あくまでデバッグ目的の機能でユーザーには何のメリットもありません。
リリースビルドのコードには含まれるべきではないため、そのままだとリジェクトされる可能性があります(実際に試した訳ではないのでご存じの方はコメント頂けると幸いです)。
#if DEBUG〜#endif 等でリリースビルド時に除外されるようにしておくと良いかもしれません。
var body: some View {
#if DEBUG
let _ = Self._printChanges()
#endif
以上
macOS Monterey(12.2.1)
Xcode 13.2.1
iOS 15.2(iPhone 13 mini シミュレータ)