You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发:UIMenu导致UIButton点击动作仅触发一次的问题

问题解决

1. 按钮点击仅第一次触发动作的问题

  • 原因:设置sender.showsMenuAsPrimaryAction = true后,按钮的主交互逻辑被替换为直接展示菜单,后续点击不会再触发绑定的buttonNewAction方法,且重复设置菜单和该属性属于冗余操作。
  • 解决:要么在初始化时一次性配置菜单;若需动态更新菜单,可在按钮点击时重新生成菜单并手动触发展示,同时调整showsMenuAsPrimaryAction的使用方式。

2. 菜单选项点击时随机数固定的问题

  • 原因:randomNumber在创建UIAction时生成,闭包会捕获这个固定值,后续点击菜单选项都会复用第一次的数值。
  • 解决:将随机数生成逻辑移到UIAction的闭包内部,确保每次点击菜单选项时都会重新生成随机数。

修改后的代码

import UIKit
class ViewController: UIViewController {

    var name = String()
    var namesText = ["one", "Two", "Three", "Four", "Five", "six", "Seven","Eight", "Nine", "Ten"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // 若按钮是通过IBOutlet关联,可直接用关联属性替代tag查找
        if let menuButton = view.viewWithTag(100) as? UIButton {
            setupMenu(for: menuButton)
        }
    }

    // 统一配置菜单的方法
    func setupMenu(for sender: UIButton) {
        let usersItem = UIAction(title: "Users", image: UIImage(systemName: "person.fill")) { _ in
            let randomNumber = Int(arc4random_uniform(10))
            print("\(randomNumber) in User action")
        }
        
        let addUserItem = UIAction(title: "Add User", image: UIImage(systemName: "person.badge.plus")) { _ in
            let randomNumber = Int(arc4random_uniform(10))
            print("\(randomNumber) in add user action")
        }
        
        let removeUserItem = UIAction(title: "Remove User", image: UIImage(systemName: "person.fill.xmark.rtl")) { _ in
            let randomNumber = Int(arc4random_uniform(10))
            print("\(randomNumber) in Remove user")
        }
        
        let menu = UIMenu(title: "", children: [usersItem, addUserItem, removeUserItem])
        sender.menu = menu
    }

    @IBAction func buttonNewAction(_ sender: UIButton) {
        // 这里可添加每次点击按钮都需要执行的逻辑
        print("按钮被点击")
        // 若需动态更新菜单,重新生成
        setupMenu(for: sender)
        // 手动触发菜单展示
        sender.showMenu(from: sender, rect: sender.bounds, in: view)
    }
}

补充说明

如果不需要每次点击都更新菜单,可将setupMenu的调用移到viewDidLoad中,并设置sender.showsMenuAsPrimaryAction = true,这样点击按钮会直接展示菜单,无需手动调用showMenu。

内容的提问来源于stack exchange,提问作者Logger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:10:59