从托管控制器重新加载 SwiftUI 视图

Reload SwiftUI View from a hosting controller

有没有办法从其托管控制器重新加载 swiftUI 视图?

我有一个 WKHostingController,它的 body 有一个 swiftUI 视图。当视图外的通知被触发时,我需要更新视图。如果我尝试更改 @Binding 或 @State 变量,我会收到错误消息

I can't update values outside of the view

但是我找不到刷新方法。

有什么想法吗?

托管控制器:

class WorkoutListInterfaceController : WKHostingController<WorkoutListView> {
  override var body: WorkoutListView {
    WorkoutListView(host: self)
  }


  override func didAppear() {
    // update WorkoutListView!!!
  }

  func showExercises(forWorkout workout: Workout) {
    WKInterfaceController.reloadRootControllers(withNamesAndContexts: [(name: "ExerciseListInterfaceController", context: workout as AnyObject)])
  }

  func showAddWorkout() {
    presentController(withNamesAndContexts: [("AddWorkoutHostingController", context: "" as AnyObject)])
  }
}

SwiftUI 视图:

struct WorkoutListView : View {
  weak var host: WorkoutListInterfaceController?

  @State private var shouldPresentAddWorkout = false
  @State var workouts: [Workout] = Workout.all()

  init(host: WorkoutListInterfaceController) {
    self.host = host
  }

  var body: some View {
    return List {
      Section(header: Text("Workouts")
        .font(.system(size: 18))
        .fontWeight(.bold)
        .frame(height: 18))
      {
        ForEach(workouts) { workout in
          Button(action: {
            self.host?.showExercises(forWorkout: workout)
          }) {
            Text(workout.title)
          }
        }
      }

      Button(action: {
        self.host?.showAddWorkout()
      }) {
        Text("Add Workout")
          .fontWeight(.medium)
          .foregroundColor(.green)
          .frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
      }
    }
    .sheet(isPresented: $shouldPresentAddWorkout, onDismiss: {}) {
      AddWorkoutView(host: AddWorkoutHostingController())
    }
    .contextMenu {
      Button(action: { self.host?.showAddWorkout() },
             label: {
              VStack {
                Image(systemName: "plus")
                Text("Add Workout")
              }
      })
    }
  }
}

WorkoutListInterfaceControllerdidAppear() 被调用,我想更新 WorkoutListView

onAppear() 上,不会调用 swiftUI 视图修改器。我不知道这是错误还是预期行为,这就是为什么我默认使用托管控制器上的 didAppear() 来刷新视图。

通过在呈现的视图将关闭时发布通知,使其与 Combine 和 NotificationCenter 一起使用:

NotificationCenter.default.post(name: .updateWorkoutsNotification, object: workouts)

然后在 WorkoutListView 视图模型中订阅该通知

你试过了吗:

. setNeedsBodyUpdate()

https://developer.apple.com/documentation/swiftui/wkhostingcontroller/setneedsbodyupdate()