NoneBuild Menu вызывается в AppDelegate, но не UIViewController
Я пытаюсь создать пользовательское меню для каждого представления в моем приложении, однако кажется, что buildMenu не вызывается в View Controllers. Вот пример:
В моем 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")
}
но buildMenu в UIViewController никогда не вызывается:(
Есть идеи, если это предполагаемое поведение или есть какие-то обходные пути?
1 ответ
Для основных меню система только консультируется UIApplication
а также UIApplicationDelegate
, поскольку основные меню могут существовать без какого-либо окна и, следовательно, без каких-либо UIViewController
иерархия. Вот почему ваше переопределение на UIViewController
не вызывается для основных меню.
Для контекстных меню система проверяет всю цепочку респондента, начиная с представления.
Если вам нужно обновить команды главного меню в зависимости от их контекста:
- Вы могли бы уйти
buildMenu(with:)
вUIApplicationDelegate
договориться с делегатом, чтобы выяснить, когда и что изменилось, и позвонитьUIMenu.main.setNeedsRebuild()
когда это изменится, или - Вы можете определить частный метод
buildMyMenu(with:)
в вашейUIViewController
подклассы, и организовать дляbuildMenu(with:)
вUIApplicationDelegate
позвонить или - Вы можете построить статическое меню в
buildMenu
и полагаться на свои переопределенияcanPerformAction(_:withSender:)
а такжеvalidate(_:)
включить или отключить или даже скрыть определенные команды, например, путем обновленияattributes
собственность в вашемvalidate(_:)
переопределения.
Это предполагаемое поведение. Цитата из документов:
Поскольку меню могут существовать без иерархии окон или представлений, система обращается только к
UIApplication
а такжеUIApplicationDelegate
для создания строки меню приложения.
На той же странице документации объясняется, как вы можете настраивать команды меню из контроллеров представления, а также есть отличный пример проекта, поэтому обязательно проверьте его.