前書き
なんで何回も呼ばれるんや!!!
initすな!!!
なんのためのStateObjectや!!!と思い調べました。
備忘録としてですがめちゃめちゃ困ったので同じ事象で困っている人のためになれば嬉しいです。
確認OS:iOS14.1~15.4
DeploymentInfo :iOS14.1
結論
これを追加するだけ
//呼び出されるViewの方で使用しなくてもこれを宣言しましょう
@Environment(\.presentationMode) var presentation
発生するときのサンプル
import SwiftUI
struct BaseView: View {
@State var showSheet: Bool = false
var body: some View {
Text("テスト!")
.padding()
Button("モーダル表示", action: {
self.showSheet = true
})
.sheet(isPresented: $showSheet, content: {
SheetView()
})
}
}
struct SheetView: View {
init() {
print("init呼ばれたよ")
}
var body: some View {
Text("シートビューだよ")
.padding()
.onAppear(perform: {
print("View appeared")
})
}
}
こういう時にBaseViewでボタンをタップするとSheetViewのinitが何度も呼ばれるケースがあります。
サンプルのケースではinitでprintしているだけなのでいいのですが(良くない)、一度しか初期化したくない@StateObjectを使用している時にも何度もインスタンスが作成されることで初期化されてしまいます。
#対応したサンプル
import SwiftUI
struct BaseView: View {
@State var showSheet: Bool = false
var body: some View {
Text("テスト!")
.padding()
Button("モーダル表示", action: {
self.showSheet = true
})
.sheet(isPresented: $showSheet, content: {
SheetView($showSheet)
})
}
}
struct SheetView: View {
@Environment(\.presentationMode) var presentation
@Binding var showSheet:Bool
init(_ showSheet:Bool) {
print("init呼ばれたよ")
}
var body: some View {
Text("シートビューだよ")
.padding()
.onAppear(perform: {
print("View appeared")
})
Button("モーダル閉じる", action: {
self.showSheet = false
})
}
}
これだけです。
どうやらiOS側のバグのようです。