iPadOS多窗口SwiftUI应用中聚焦值与对象无法随激活窗口更新的问题咨询
iPadOS多窗口SwiftUI应用中聚焦值与对象无法随激活窗口更新的问题咨询
我正在开发一个支持多窗口的SwiftUI应用(采用SwiftUI生命周期),在WindowGroup上通过.commands定义了主菜单命令。应用结构很简单,包含一个带有MasterView和DetailView的NavigationSplitView。
在层级较深的DetailView中,我使用focusedSceneObject和focusedSceneValue来把DetailViewModel和当前选中的Item传递给AppCommands,这样菜单命令就能和当前激活的DetailView交互。
先贴我的DetailView代码:
struct DetailView: View { @StateObject private var viewModel: DetailViewModel = .init() let item: Item? var itemTitle: String { item?.title ?? "nil" } var body: some View { let _ = Self._printChanges() Group { if let item = item { SelectedItemView(viewModel: self.viewModel, item: item) } else { ContentUnavailableView("Select an Item", systemImage: "list.bullet", description: Text("Choose an item from the list to see its details")) } } .alert( "Alert", isPresented: self.$viewModel.presentedAlert, actions: { Button("OK", role: .cancel) { self.viewModel.presentedAlert = false } }, message: { Text("Presented from detail view with item: \(self.itemTitle)") }) .navigationTitle(item?.title ?? "Detail") .onChange(of: self.item) { _, newValue in viewModel.updateItem(newValue) } // 通过@FocusedValue/@FocusedObject向AppCommands传递当前选中的Item和viewModel .focusedSceneValue(\.selectedItem, self.item) .focusedSceneObject(self.viewModel) } }
接下来是应用的主结构和AppCommands的实现:
@main struct MyApp: App { var body: some Scene { WindowGroup(id: "main") { ContainerView() } .commands { AppCommands() } } } // MARK: - AppCommands struct AppCommands: Commands { @FocusedValue(\.selectedItem) private var selectedItem: Item? @FocusedObject private var viewModel: DetailViewModel? var body: some Commands { let _ = print("AppCommands") let _ = print("Focused view model: \(pointer(self.viewModel))") let _ = print("Focused selectedItem: \(selectedItem?.title ?? "nil")") CommandGroup(after: .newItem) { Button("Focused View Model Command") { print("executing command with focused view model: \(pointer(self.viewModel))") viewModel?.presentedAlert = true } .keyboardShortcut(.return, modifiers: [.command]) Button("Selected Item Command") { print("executing command with selected item: \(self.selectedItem?.title ?? "nil")") } .keyboardShortcut(.return, modifiers: [.command, .shift]) } } }
我的需求很明确:当DetailView显示时,通过主菜单执行命令(或按下快捷键),应该对当前显示的DetailView对应的viewModel执行操作。这个逻辑在Mac上多窗口的情况下完全正常,但在iPad上打开两个分屏窗口(Split View)时,切换激活窗口(点击窗口切换),@FocusedObject和@FocusedValue并不会正确更新为当前激活窗口的Item和viewModel,还是保留着之前窗口的内容。
我已经录屏演示了这个问题,现在想请教大家:
- 是我的写法哪里有问题吗?
- 还是这是iPadOS上SwiftUI的一个bug?
- 有没有什么办法可以解决这个问题,让菜单命令能正确关联当前激活窗口的DetailView数据?
内容来源于stack exchange
相关产品推荐
相关产品推荐

