【问题标题】:UndoManager.setActionName not displayed in menu (SwiftUI macOS)UndoManager.setActionName 未显示在菜单中(SwiftUI macOS)
【发布时间】:2021-03-26 20:46:14
【问题描述】:

编辑菜单的撤消/重做显示的标题不反映this demo SwiftUI macOS app 中的setActionName。撤消/重做功能工作正常,管理器报告它已设置操作标题。

为什么菜单没有更新?

autoenablesItems 对 NSApp.menu 是 true。当循环遍历 NSApp 中的所有窗口(只有一个窗口)时,UndoManager(只有一个用于应用程序)与 SwiftUI 通过 Environment 呈现的实例相同。通过 NSApp 的参考检查撤消项目标题也显示项目标题已设置,即使它没有显示在编辑菜单中。


struct ContentView: View {
    @Binding var document: DocumentTestDocument
    @Environment(\.undoManager) var undo
    @StateObject var vm = VM()
    
    @State var autoEnables = false
    
    var body: some View {
        VStack(spacing: 25) {
            HStack {
                Button("<") { vm.performUndo(undo: undo) }
                    .disabled(!(undo?.canUndo ?? true))
                
                Button("Up") { vm.increment(undo: undo) }
                Button("Down") { vm.decrement(undo: undo) }
                
                Button(">") { vm.performRedo(undo: undo) }
                    .disabled(!(undo?.canRedo ?? true))
            }
            
            Text(String(vm.count))
                .font(.title)
            
            Text("MenuItemTitle \(vm.title)")
            
        }
        .controlSize(.large)
        .font(.title3)
        .frame(width: 400, height:  300)
        .onAppear { DispatchQueue.main.async { autoEnables = NSApp.menu?.autoenablesItems ?? false } }
    }
}

class VM: ObservableObject {
    
    @Published var count = 0
    @Published var title = ""
    
    func increment(undo: UndoManager?) {
        count += 1
        
        undo?.registerUndo(withTarget: self, handler: { (targetSelf) in
            targetSelf.decrement(undo: undo)
        })
        undo?.setActionName("Increment")
        
        title = undo?.undoMenuItemTitle ?? "Nil"
    }
    
    func decrement(undo: UndoManager?) {
        count -= 1
        
        undo?.registerUndo(withTarget: self, handler: { (targetSelf) in
            targetSelf.increment(undo: undo)
        })
        undo?.setActionName("Increment")
        
        title = undo?.undoMenuItemTitle ?? "Nil"
    }
    
    func performUndo(undo: UndoManager?) {
        undo?.undo()
    }
    
    func performRedo(undo: UndoManager?) {
        undo?.redo()
    }
}

【问题讨论】:

  • 嗨瑞恩,我遇到了完全相同的问题。你可能找到解决方案了吗?
  • 没有。我也没有成功通过 windowWillReturnUndoManager 将新弹出的 NSWindow 的 UndoManager 设置为主文档,尽管撤消仍然注册并且可以在主窗口中撤消。

标签: macos swiftui


【解决方案1】:

由于某种原因,这没有在新的 SwiftUI App 生命周期中实现。如果您在情节提要中设置 Edit 菜单并自己配置 NSHostingView,则 Undo 菜单项标题将随着您现有的代码正确更改。我当然希望这个功能能尽快推出,因为名副其实的撤消是我最喜欢的精美 Mac 应用程序的一部分!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    相关资源
    最近更新 更多