ios SwiftUI视图在类中的数组更新时不更新

wz8daaqr  于 2023-10-21  发布在  iOS
关注(0)|答案(1)|浏览(179)

我在更新视图以反映从WebSocket回复传入的每个新实体PosArray时遇到了麻烦。它在这个类中更新,但不在视图中更新,我没有办法测试了。
我认为它在“entityPositionClassArray = entityPosArray”这一行附近,这一行没有注册为@ObservedObject update?如果我使用一个按钮动作来触发AlternityPositions(),它确实有效,但是在每个更新的Array上进行实时视图更新之后。
示例实体PosArray:

[["EntID": "0012", "entPOSX": "1064.55", "entPOSY": "871.31"], 
["EntID": "5699", "entPOSX": "2231.13", "entPOSY": "1962.92"], 
["EntID": "5540", "entPOSX": "-1619.95", "entPOSY": "-1344.04"], 
["EntID": "5989", "entPOSY": "731.11", "entPOSX": "-1689.66"], 
["EntID": "0809", "entPOSX": "-971.65", "entPOSY": "-1761.38"]]

到目前为止,我们只是试图让array.count在视图中更新,之后剩下的应该是simular。我可以看到控制台中的数据从类更新,但没有看到视图重新加载或文本字段更新。

import SwiftUI
import Combine
import Foundation

class EntityPositionViewModel: ObservableObject {
    
    @Published var entityPositionClassArray = [[String:String]]()
    @Published var entityOnline: Int = 0
    
    func EntityPositions() {
        entityPositionClassArray = entityPosArray
        entityOnline = entityPositionClassArray.count           // Added to test in console
        let _ = print("There are \(entityOnline) connected")    // <- This works on each Array update
    }
}

struct EntityOnline: View {
    
    @ObservedObject var model = EntityPositionViewModel()
    
    init() {
        model.EntityPositions()                 // init() makes no difference
        }
    
    var body: some View {
        VStack {
            Text("Test: \(model.entityOnline)")
                .font(.largeTitle)
            
            // Testing for View Update and Reload
            let entityOnline2 = model.entityPositionClassArray.count // Checking different call
            let _ = print("TestEnts: \(entityOnline2)")
            let _ = print("View Reloaded")
        }
    }
}```
gk7wooem

gk7wooem1#

正如@5318223所说,你没有在任何地方调用你的模型来触发更新,那么你为什么要期待一个更新呢?
您可以尝试从View结构体中删除init方法,并将其替换为onAppear修饰符,这将触发视图更新。

import SwiftUI
import Combine
import Foundation

class EntityPositionViewModel: ObservableObject {
    
    @Published var entityPositionClassArray = [[String:String]]()
    @Published var entityOnline: Int = 0
    
    func EntityPositions() {
        entityPositionClassArray = entityPosArray
        entityOnline = entityPositionClassArray.count           // Added to test in console
        let _ = print("There are \(entityOnline) connected")    // <- This works on each Array update
    }
}

struct EntityOnline: View {
    
    @ObservedObject var model = EntityPositionViewModel()
    
    var body: some View {
        VStack {
            Text("Test: \(model.entityOnline)")
                .font(.largeTitle)
            
            // Testing for View Update and Reload
            let entityOnline2 = model.entityPositionClassArray.count // Checking different call
            let _ = print("TestEnts: \(entityOnline2)")
            let _ = print("View Reloaded")
        }.onAppear {
                model.EntityPositions()
        }
    }
}

然而,这将在视图的每一次出现时被调用,所以可能不是你想要的。一般来说,你会在View上有一个按钮,它会触发视图模型上的某种状态更新,如下所示:

import SwiftUI
import Combine
import Foundation

class ViewModel: ObservableObject {
    @Published var count: Int = 0

    func didTapButton() {
        count += 1
    }
}

struct SomeView: View {
    @StateObject var viewModel: ViewModel = ViewModel()

    var body: some View {
        Text("Count is: \(viewModel.count)")
        Button("Increase Count") {
            viewModel.didTapButton()
        }
    }
}

还请注意,我使用了StateObject,因为在本例中,View是创建ViewModel的对象。

相关问题