Home > Back-end >  Getting the current UIButton menu selected item
Getting the current UIButton menu selected item

Time:05-17

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?

CodePudding user response:

You can fetch the selected item into the action block

let saveAction = { (action: UIAction) in
    //action
    print(action.title)
}

CodePudding user response:

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)
}
  • Related