【问题标题】:SwiftUI change on multilevel children Published object change多级子级的 SwiftUI 更改已发布的对象更改
【发布时间】:2021-05-09 13:35:45
【问题描述】:

我有一个 ObservedObject AppStatus 类,它内部有多个 Published 类。如果我只有孩子方面的水平,那么一切都很好。

当我有一个类 RecordingTimeManager 内部有另一个变量(2 级子级)时,问题就来了。当我按下按钮时,变量 maxRecordingTime 正在正确更改,它会打印“15 FifthSeconds”,但前景颜色没有触发更改。我不确定这是否是 SwiftUI 错误,或者我应该以另一种方式构建关系:

// 应用状态

// Recording
@Published var recordingTimeManager: RecordingTimeManager = RecordingTimeManager()

// 录音时间管理器

class RecordingTimeManager {
    @Published var maxRecordingTime: TimeSeletedTime = .sixteenSeconds
...

// 需要根据 maxRecordingTime 更改来更改不透明度的 SwiftUI 组件(.foregroundColor 不会更改)

Button {
    appStatus.recordingTimeManager.maxRecordingTime = .fifteenSeconds
    print("15 \(appStatus.recordingTimeManager.maxRecordingTime)")
} label: {
    Text("15")
        .font(Font.custom("BwGradual-Bold", size: 15))
        .foregroundColor(appStatus.recordingTimeManager.maxRecordingTime == .fifteenSeconds ? CLAPSOFFWHITE : TRIBESGREY)
}

非常感谢,

【问题讨论】:

  • 你能再分享一些代码吗?另外,您是否缺少添加 ObservableObject 协议?
  • 将 RecodingTimeManager 设为 Struct 并从中删除 @published 属性。

标签: swift swiftui


【解决方案1】:

可观察对象不仅仅在你有多个级别的类时工作。 @Published 属性包装器会在属性更改时通知视图,但由于此属性是 class - 一种引用类型 - 当您更改其中一个属性时,它实际上并没有更改。换句话说,引用保持不变。

而内部的@Published 什么也不做,因为没有任何东西可以直接观察它(即使RecordingTimeManager 符合ObservableObject

因此,您要么需要将 RecordingTimeManager 设为值类型 - struct

struct RecordingTimeManager {
   var maxRecordingTime: TimeSeletedTime = .sixteenSeconds
}

或者,如果它必须是class(可能是因为它有一些内部状态和生命周期),那么你可以创建一个直接观察它的内部视图。

首先,它必须是ObservableObject

class RecordingTimeManager: ObservableObject {
    @Published var maxRecordingTime: TimeSeletedTime = .sixteenSeconds

然后创建一个观察它的视图(可能是私有内部视图):

struct MainView: View {
   @StateObject var appStatus: AppStatus = .init()

   private struct InnerView: View {
      @ObservedObject var recordingManager: RecordingTimeManager

      var body: some View {
         Button {
           recordingManager.maxRecordingTime = .fifteenSeconds
         } label: {
           Text("15")
             .font(Font.custom("BwGradual-Bold", size: 15))
             .foregroundColor(
                 recordingManager.maxRecordingTime == .fifteenSeconds 
                    ? CLAPSOFFWHITE : TRIBESGREY)
         }
      }
   }

   var body: some View {

      InnerView(recordingManager: appStatus.recordingTimeManager)
   }
}

【讨论】:

    猜你喜欢
    • 2020-03-13
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 2022-01-18
    • 2020-11-26
    • 2016-08-22
    • 1970-01-01
    • 2017-06-01
    相关资源
    最近更新 更多