首页 > 解决方案 > 当数组值随 SwiftUI 变化时如何更新视图中的 ForEach

问题描述

我在这里有这个代码用于更新基于计时器的数组和字典:

class applicationManager: ObservableObject {
    static var shared = applicationManager()
    
    @Published var applicationsDict: [NSRunningApplication : Int] = [:]
    @Published var keysArray: [NSRunningApplication] = []
}


class TimeOpenManager {
    var secondsElapsed = 0.0
    var timer = Timer()
    
    func start() {
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
            self.secondsElapsed += 1
            let applicationName = ws.frontmostApplication?.localizedName!
            let applicationTest = ws.frontmostApplication
            
            let appMan = applicationManager()
            
            if let appData = applicationManager.shared.applicationsDict[applicationTest!] {
                applicationManager.shared.applicationsDict[applicationTest!] = appData + 1
            } else {
                applicationManager.shared.applicationsDict[applicationTest!] = 1
            }
            
            applicationManager.shared.keysArray = Array(applicationManager.shared.applicationsDict.keys)
            
        }
    }
}

它像这样工作正常,并且在计时器运行时使用 applicationsDict 键更新 keysArray。但是即使更新了 keysArray,在添加值时HStack ForEachin WeekView也不会改变。

我也有这个正在加载keysArray的视图:

struct WeekView: View {
    static let shared = WeekView()
    
    var body: some View {
        VStack {
            HStack(spacing: 20) {
                ForEach(0..<8) { day in
                    if day ==  weekday {
                        Text("\(currentDay)")
                            .frame(width: 50, height: 50, alignment: .center)
                            .font(.system(size: 36))
                            .background(Color.red)
                            .onTapGesture {
                                print(applicationManager.shared.keysArray)
                                print(applicationManager.shared.applicationsDict)
                            }
                    } else {
                        Text("\(currentDay + day - weekday)")
                            .frame(width: 50, height: 50, alignment: .center)
                            .font(.system(size: 36))
                    }
                }
            }
            HStack {
                ForEach(applicationManager.shared.keysArray, id: \.self) {dictValue in
                    Image(nsImage: dictValue.icon!)
                        .resizable()
                        .frame(width: 64, height: 64, alignment: .center)
                }
            }
        }
    }
}

标签: swiftxcodeswiftui

解决方案


正如评论中提到的,applicationManager应该是一个ObservableObjectwith@Published属性。

然后,你需要告诉你的视图它应该从这个对象中寻找更新。您可以使用@ObservedObject属性包装器来做到这一点:

struct WeekView: View {
  @ObservedObject private var manager = applicationManager.shared

然后:

ForEach(manager.keysArray) {

替换您applicatoinManager.sharedmanagerWeekView

补充阅读:https ://www.hackingwithswift.com/quick-start/swiftui/how-to-use-observedobject-to-manage-state-from-external-objects


推荐阅读