Как использовать свойство BaseView @State в SubView SwiftUI
У меня есть что-то вроде этого BaseView, и я хочу добавить механизм предупреждений ко всем моим подпредставлениям
struct BaseView<Content: View>: View {
@State var isAlertPresented = false
let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body : some View {
content.alert(isPresented: $isAlertPresented) {
Alert(title: Text("title"))
}
}
}
А вот и мой SubView.
struct SubView: View {
BaseView {
Text("")
}.onReceive(vm.publisher) { (output) in
// here I want to trigger BaseView isAlertPresented property
// BaseView.isAlertPresented = true
}
}
Могу я сделать что-то подобное? Если да, то как я могу?
1 ответ
Решение
Если представление содержит BaseView, это определенно не относящееся к нему подпредставление. И вы не должны получать доступ / манипулировать внутренним состоянием другого представления из-за нарушения единого источника истины.
Вместо этого вы должны использовать привязку в этом сценарии, как показано ниже (протестировано с Xcode 11.7)
struct BaseView<Content: View>: View {
@Binding var isAlertPresented: Bool
let content: Content
init(isAlertPresented: Binding<Bool>, @ViewBuilder content: () -> Content) {
self._isAlertPresented = isAlertPresented
self.content = content()
}
var body : some View {
content.alert(isPresented: $isAlertPresented) {
Alert(title: Text("title"))
}
}
}
struct SomeOtherView: View {
@State private var showAlert = false
var body: some View {
BaseView(isAlertPresented: $showAlert) {
Text("Test")
}
.onReceive(vm.publisher) { (output) in
// .onAppear { // used instead of above just for test
self.showAlert = true
}
}
}