我正在尝试为我的应用程序中的每个视图创建一个自定义菜单,但是看来buildMenu没有在视图控制器中调用。这是一个例子:
在我的AppDelegate中,使用了此代码,该代码可以按预期100%运行。
override func buildMenu(with builder: UIMenuBuilder) { print("Updating menu from AppDelegate") super.buildMenu(with: builder) let command = UIKeyCommand( input: "W", modifierFlags: [.command], action: #selector(self.helloWorld(_:)) ) command.title = "Hello" builder.insertChild(UIMenu( __title: "World", image: nil, identifier: UIMenu.Identifier(rawValue: "com.hw.hello"), options: [], children: [command] ), atEndOfMenu: .file) } @objc private func helloWorld(_ sender: AppDelegate) { print("Hello world") }
但是我需要根据用户在应用程序中的位置来更改菜单中可用的选项,因此我尝试在UIViewController中执行此操作:
override func viewDidAppear(_ animated:Bool){ // Tried all of these to see if any work UIMenuSystem.main.setNeedsRebuild() UIMenuSystem.context.setNeedsRebuild() UIMenuSystem.main.setNeedsRevalidate() UIMenuSystem.context.setNeedsRevalidate() }
然后再次..
// This is never called override func buildMenu(with builder: UIMenuBuilder) { print("Updating menu in View Controller") }
但是从不调用UIViewController中的buildMenu :(
有什么想法是预期的行为还是有任何解决方法?
对于主菜单,系统仅查询UIApplication
和UIApplicationDelegate
,因为主菜单可以存在而没有任何窗口,因此也没有任何UIViewController
层次结构。这就是为什么UIViewController
主菜单不会调用您的覆盖。
对于上下文菜单,系统确实从视图开始参考完整的响应者链。
如果您需要根据其上下文更新主菜单命令:
您可以留buildMenu(with:)
在中UIApplicationDelegate
,安排委托人找出更改的时间和内容,并在更改时致电UIMenu.main.setNeedsRebuild()
,或者
您可以buildMyMenu(with:)
在UIViewController
子类中定义一个私有方法,并安排buildMenu(with:)
在其中UIApplicationDelegate
调用它,或者
您可以在中建立一个静态菜单buildMenu
,并依赖于您的替代,canPerformAction(_:withSender:)
并validate(_:)
启用或禁用甚至隐藏特定命令,例如通过更新替代中的attributes
属性validate(_:)
。