skip to Main Content

I have a uibutton with a menu and several actions.

Whenever the user select a menu item I want to fetch it and print it.

This is my button:

   private lazy var measurementField: UIButton = {
    let saveAction = { (action: UIAction) in
        //action
    }
    let saveMenu = UIMenu(children: [
        UIAction(title: Ingredient.Measurements.oz.rawValue, image: nil, handler: saveAction),
        UIAction(title: Ingredient.Measurements.grams.rawValue, image: nil, handler: saveAction),
        UIAction(title: Ingredient.Measurements.cups.rawValue, image: nil, handler: saveAction),
        UIAction(title: Ingredient.Measurements.tsp.rawValue, image: nil, handler: saveAction),
        UIAction(title: Ingredient.Measurements.tbsp.rawValue, image: nil, handler: saveAction),
        UIAction(title: Ingredient.Measurements.quarts.rawValue, image: nil, handler: saveAction),
        UIAction(title: Ingredient.Measurements.pints.rawValue, image: nil, handler: saveAction),
    ])
    var config = UIButton.Configuration.filled()
    config.baseBackgroundColor = .label
    let button = UIButton(configuration: config)
    button.menu = saveMenu
    button.showsMenuAsPrimaryAction = true
    button.changesSelectionAsPrimaryAction = true
    button.addTarget(CreateFormViewController(), action: #selector(CreateFormViewController.linkData), for: .touchUpInside)
    return button
}()

This is my selector (the action that should be triggered):

@objc public func linkData(..more params... , _ sender:UIButton?) { 
    ...
    print(sender?.menu?.title)
    ...
}

It only prints ‘nil’ tho.
How can I fetch that menu-selected item?

2

Answers


  1. You can fetch the selected item into the action block

    let saveAction = { (action: UIAction) in
        //action
        print(action.title)
    }
    
    Login or Signup to reply.
  2. UIMenu doesn’t have ‘selectedItem’. When your action method linkData is called you are trying to print title of menu, not title of UIAction. If you look on full initializer of UIMenu, you will see that UIMenu initializer has ‘title’ property, which by default is setted as "" (empty String).

    public convenience init(title: String = "", image: UIImage? = nil, identifier: UIMenu.Identifier? = nil, options: UIMenu.Options = [], children: [UIMenuElement] = [])
    

    If you want to print a title of your action item, you have to do it in your handler closure:

    let saveAction = { (action: UIAction) in
      //do your stuff here
    }
    

    p.s. If you want to make references to self or any other class-object in your controller, don’t forget to capture this reference as unowned/weak to avoid retain cycle:

    let saveAction = { [weak self] (action: UIAction) in
      self?.printActionItemTitle(action.title)
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search