繁体   English   中英

SwiftUI - 使用 onChange 方法未检测到嵌套视图 Model 类中的更改

[英]SwiftUI - changes in nested View Model classes not detected using onChange method

我有一个嵌套视图 Model class WatchDayProgramViewModel作为 ObservableObject。 WatchDayProgramViewModel中,有一个WorkoutModel是一个孩子 class。我想检测currentHeartRate中的任何更新以触发数据传输到 iPhone。

因此,我尝试从 ContentView 使用WatchDayProgramViewModel作为EnvironmentObject并通过onChange()方法检测WorkoutModel中的变化。 但似乎 SwiftUI 视图没有检测到WorkoutModel中的任何属性更改。

我知道这个问题可能是由于 ObservableObject 没有检测到子类/嵌套级别的变化,所以答案( SwiftUI 多级子级的变化发布 object 变化)建议使用struct而不是 class。但是将WorkoutModel更改为struct导致各种@Published@Published的属性和函数以显示错误。

是否有任何可能的方法从ContentView本身检测子视图 Model 的变化?

内容视图

struct ContentView: View {
    @State var selectedTab = 0
    @StateObject var watchDayProgramVM = WatchDayProgramViewModel()
    
    var body: some View {
    
        NavigationView {
TabView(selection: $selectedTab) {
                    
                    WatchControlView().id(0)
                    NowPlayingView().id(1)
                }
                .environmentObject(watchDayProgramVM)
                .onChange(of: self.watchDayProgramVM.workoutModel.currentHeartRate) { newValue in
                                        print("WatchConnectivity heart rate from contentView \(newValue)")
   
                }
       }
}

WatchDayProgramViewModel

class WatchDayProgramViewModel: ObservableObject {
    
    @Published var workoutModel = WorkoutModel()
    
    init() {
    }
    
}

锻炼模式

import Foundation
import HealthKit

class WorkoutModel: NSObject, ObservableObject {
    
    let healthStore = HKHealthStore()
    var session: HKWorkoutSession?
    var builder: HKLiveWorkoutBuilder?
    
    @Published var currentHeartRate: Double = 0
    @Published var workout: HKWorkout?

//Other functions to start/run workout hidden

func updateForStatistics(_ statistics: HKStatistics?) {
        
        guard let statistics = statistics else {
            return
        }
        
        DispatchQueue.main.async {
            switch statistics.quantityType {
            case HKQuantityType.quantityType(forIdentifier: .heartRate):
                
                let heartRateUnit = HKUnit.count().unitDivided(by: HKUnit.minute())
                
                self.currentHeartRate = statistics.mostRecentQuantity()?.doubleValue(for: heartRateUnit) ?? 0
                
            default:
                return
                
            }
            
        }//end of dispatchqueue
        
    }// end of function

}

extension WorkoutModel: HKLiveWorkoutBuilderDelegate {
    
    func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) {
        
        for type in collectedTypes {
            guard let quantityType = type as? HKQuantityType else {
                return
            }

            let statistics = workoutBuilder.statistics(for: quantityType)
            updateForStatistics(statistics)
            
        }
    }
}

尝试改变

@StateObject var watchDayProgramVM = WatchDayProgramViewModel()

@ObservedObject var watchDayProgramVM = WatchDayProgramViewModel()

想办法。 只需创建另一个AnyCancellable变量来调用objectWillChange发布者。

WatchDayProgramViewModel

class WatchDayProgramViewModel: ObservableObject {
    
    @Published var workoutModel = WorkoutModel()
    var cancellable: AnyCancellable?

    init() {
        cancellable = workoutModel.objectWillChange
            .sink { _ in
                self.objectWillChange.send()
            }
    }
    
}

虽然我已经提供了我的答案,但我很乐意看到/获得有关其他替代方案的建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM