Показывать UIMenu при однократном нажатии на UIBarButtonItem
В iOS 14 есть новые API для UIMenu
, и теперь его можно прикрепить к UIBarButtonItem
, вот так: ИЗОБРАЖЕНИЕ
Это мой код:
@IBOutlet weak var addButton: UIBarButtonItem! // The button is from the storyboard.
override func viewDidAppear(_ animated: Bool) {
if #available(iOS 14.0, *) {
let simpleAction : UIAction = .init(title: "Simple", image: nil, identifier: nil, discoverabilityTitle: nil, attributes: .init(), state: .mixed, handler: { (action) in
self.addButtonActionPressed(action: .simple)
})
let advancedAction : UIAction = .init(title: "Advanced", image: nil, identifier: nil, discoverabilityTitle: nil, attributes: .init(), state: .mixed, handler: { (action) in
self.addButtonActionPressed(action: .advanced)
})
let actions = [simpleAction, advancedAction]
let menu = UIMenu(title: "", image: nil, identifier: nil, options: .displayInline, children: actions)
addButton.primaryAction = nil
addButton.menu = menu
}
}
Но проблема в том, что когда я нажимаю кнопку, ничего не происходит. Только когда я долго нажимаю на кнопку, появляется меню. Я видел этот код в Интернете:
button.showsMenuAsPrimaryAction = true
Но мне это не поможет, потому что Value of type 'UIBarButtonItem' has no member 'showsMenuAsPrimaryAction'
Есть идеи, как исправить? Я использую Xcode 12.0 beta 4 (12A8179i). Благодарность
5 ответов
Я исправил эту проблему. Если это происходит с кем-либо из вас, вы можете сделать следующее:
Попробуйте проверить, есть ли другое действие с кнопкой. Если есть, меню не будет отображаться как основное действие.
Если вы используете раскадровку, используйте вместо этого код, например:
self.navigationItem.rightBarButtonItem =.init (systemItem:.add) // Затем настройте меню элемента здесь, выполнив: navigationItem.rightBarButtonItem!.menu = menu // Замените 'menu' своим объектом меню.
Если вам известны другие советы, вы можете редактировать этот вопрос и добавлять их.
Вот как создать UIMenu для правильного UIBarButtonItem
//Initiate an array of UIAction.
let actions = [
UIAction(title: "Last month", identifier: UIAction.Identifier("last_montg"), handler: handler),
UIAction(title: "6 months", identifier: UIAction.Identifier("six_month"), handler: handler),
UIAction(title: "1 year", identifier: UIAction.Identifier("one_year"), handler: handler)
]
//Initiale UIMenu with the above array of actions.
let menu = UIMenu(title: "menu", children: actions)
//Create UIBarButtonItem with the initiated UIMenu and add it to the navigationItem.
let rightBarButton = UIBarButtonItem(title: "", image: UIImage(systemName: "calendar"), menu: menu)
self.navigationItem.rightBarButtonItem = rightBarButton
//handler to intercept event related to UIActions.
let handler: (_ action: UIAction) -> () = { action in
print(action.identifier)
switch action.identifier.rawValue {
case "last_month":
print("last_month")
case "six_month":
print("six_month")
case "one_year":
print("one_year")
default:
break
}
}
Также убедитесь, что в UIButton не добавлено никаких других действий, UIButton, установленный для UIMenu, не должен иметь никаких действий.
Если вы просто установите UIBarButtonItem menu
и это все, что вы делаете, то кнопка делает показать меню на кране.
Причина, по которой с вами этого не происходит, неизвестна - вы скрываете это. Вы делаете больше, но не рассказываете нам, что это такое. Возможно, вы подключили элемент кнопки панели к обработчику действия. Возможно, вы устанавливаете егоprimaryAction
. Но вы делаете что-то, из-за чего меню отображается только при длительном нажатии.
private func configureNavBar() {
let button = UIButton()
button.setImage(UIImage(named: "Slider"), for: .normal)
button.addTarget(self, action: #selector(handleFilterButton(sender: )), for: .touchUpInside)
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
}
// selector that's going to tigger on single tap on nav bar button
@objc private func handleFilterButton(sender: UIButton) {
let today = UIAction(title: "Toady", state: .mixed) { _ in
print("today button tapped")
}
let nextSevenDays = UIAction(title: "Next 7 Days", state: .mixed) { _ in
print("next seven day button tapped")
}
let menu = UIMenu(title: "Filter By", children: [today, nextSevenDays])
sender.showsMenuAsPrimaryAction = true
sender.menu = menu
}