![](/img/trans.png)
[英]How to notify view that the variable state has been updated from a extracted subview in SwiftUI
[英]SwiftUI: @State variable never get updated from @Published
我試圖在 model 出現錯誤時觸發警報,但它從未更新以顯示警報:
這是我在視圖中的實現:
struct ContentView: View {
@ObservedObject var viewModel: ViewModel
@State var showAlert = false
init() {
viewModel = ViewModel()
showAlert = viewModel.showAlert
}
var body: some View {
NavigationView {
Text("Hello, world!")
.padding()
}
.alert(isPresented: $showAlert) {
Alert(title: Text("This works"),
message: Text("Hello"),
dismissButton: .default(Text("got it"))
)}
}
}
這是我的模型:
class ViewModel: ObservableObject {
@Published var showAlert = false
var cancellables = Set<AnyCancellable>()
init() {
DoSomething.shared.showAlert.sink { _ in
print("got new Value")
} receiveValue: {[weak self] value in
print("value")
self?.showAlert = value
}.store(in: &cancellables)
}
}
class DoSomething {
let showAlert = PassthroughSubject<Bool, Never>()
static let shared = DoSomething()
private init() {
checkToShowAlert()
}
func checkToShowAlert() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) { [weak self] in
print("change value")
self?.showAlert.send(true)
}
}
}
你們中的任何人都知道為什么它永遠不會更新的showAlert
變量嗎?
我會非常感謝你的幫助
在您當前的代碼中,您在該時間點將ContentView
的showAlert
設置為ViewModel
的showAlert
:
init() {
viewModel = ViewModel()
showAlert = viewModel.showAlert //<-- assignment at the time of init
}
意思是,在分配時它是false
的。 因為它只是一個Bool
被分配給另一個Bool
,所以如果ViewModel
的showAlert
發生變化,沒有機制可以讓它保持更新。
最簡單的解決方案是去掉@State
變量並直接觀察@Published
屬性:
struct ContentView: View {
@ObservedObject var viewModel: ViewModel = ViewModel()
var body: some View {
NavigationView {
Text("Hello, world!")
.padding()
}
.alert(isPresented: $viewModel.showAlert) {
Alert(title: Text("This works"),
message: Text("Hello"),
dismissButton: .default(Text("got it"))
)}
}
}
擺脫視圖model object,這是主要問題。 我們不使用 SwiftUI 中的那些。 我們將 View 結構用於視圖數據,並使用@State
和@Binding
屬性包裝器使該結構的行為類似於 object,因此您需要先了解這一點。
另外,我認為您不需要為您嘗試做的事情使用 Combine ,因為您沒有使用combineLatest
等組合任何東西,但是當我們在 SwiftUI 中使用它時,我們不使用sink
或store
,而是assign
結束到@Published
的管道。
例子:
struct ContentView: View {
@State var isPresented = false
var body: some View {
NavigationView {
VStack{
Text("Hello, world!")
.padding()
Button("Show Alert") {
showAlert()
}
}
}
.alert(isPresented: $isPresented) {
Alert(title:Text("This works"),
message: Text("Hello"),
dismissButton: .default(Text("got it"))
)}
}
func showAlert() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
isPresented = true
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.