Показывать 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
    }
Другие вопросы по тегам