swift 在MacCatalyst中实现首选项菜单项

uwopmtnx  于 2023-09-30  发布在  Swift
关注(0)|答案(1)|浏览(104)

我有一个使用SwiftUI和Mac Catalyst的应用程序。当在Mac上运行时,我想用常用的键盘快捷键Command +,提供一个首选项菜单条目。通过设置包实现是毫无疑问的,因为我的偏好太复杂了。
下面是我的实现的简化示例:

import SwiftUI

@main
struct PreferencesMenuTestApp: App {
  @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
  
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

class AppDelegate: UIResponder, UIApplicationDelegate {
  
  override func buildMenu(with builder: UIMenuBuilder) {
    let preferencesCommand = UIKeyCommand(title: "Preferences…",
                                          action: #selector(showPreferences),
                                          input: ",",
                                          modifierFlags: .command)
    
//    let preferencesCommand = UIAction(title: "Preferences…") { action in
//      debugPrint("show preferences")
//    }
    
    let menu = UIMenu(title: "Preferences…",
                      options: .displayInline,
                      children: [preferencesCommand])
    
    builder.insertSibling(menu, afterMenu: .about)
  }
  
  
  @objc
  func showPreferences() {
    debugPrint("show preferences")
  }
}

问题是菜单项被禁用。显然,所提供的选择器未被识别。当我将AppDelegate标记为@main时,菜单项被启用。当然,应用程序的窗口是空的。当我切换到UIAction实现(注解掉的代码)时,它工作得很好。但由于无法为UIAction s提供键盘快捷键,因此这不是一个好的解决方案。
我错过了什么?如何实现一个真正有效的首选项菜单项?

wljmcqd8

wljmcqd81#

由于这是一个催化剂应用程序,在你的响应链中的一些对象需要响应showPreferences方法。这些对象通常是ViewControllers或您的应用程序示例-所有这些都继承自UIResponder。根据您提供的信息,我猜您的AppDelegate可能需要提供以下方法:

// MARK: Responder chain stuff
    override var canBecomeFirstResponder: Bool {
        return true
    }
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(showPreferences) {
            return true
        } 
        return super.responds(to: aSelector)
    }

    @objc
    func showPreferences() {
        //do something like start a new scene with your preferences
    }

相关问题