从托管控制器重新加载 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")
}
})
}
}
}
WorkoutListInterfaceController
的 didAppear()
被调用,我想更新 WorkoutListView
。
在 onAppear()
上,不会调用 swiftUI 视图修改器。我不知道这是错误还是预期行为,这就是为什么我默认使用托管控制器上的 didAppear()
来刷新视图。
通过在呈现的视图将关闭时发布通知,使其与 Combine 和 NotificationCenter 一起使用:
NotificationCenter.default.post(name: .updateWorkoutsNotification, object: workouts)
然后在 WorkoutListView 视图模型中订阅该通知
你试过了吗:
. setNeedsBodyUpdate()
https://developer.apple.com/documentation/swiftui/wkhostingcontroller/setneedsbodyupdate()
有没有办法从其托管控制器重新加载 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")
}
})
}
}
}
WorkoutListInterfaceController
的 didAppear()
被调用,我想更新 WorkoutListView
。
在 onAppear()
上,不会调用 swiftUI 视图修改器。我不知道这是错误还是预期行为,这就是为什么我默认使用托管控制器上的 didAppear()
来刷新视图。
通过在呈现的视图将关闭时发布通知,使其与 Combine 和 NotificationCenter 一起使用:
NotificationCenter.default.post(name: .updateWorkoutsNotification, object: workouts)
然后在 WorkoutListView 视图模型中订阅该通知
你试过了吗:
. setNeedsBodyUpdate()
https://developer.apple.com/documentation/swiftui/wkhostingcontroller/setneedsbodyupdate()