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

iOS技术问询:如何检测设置showMenuAsPrimaryAction的UIButton即将展示菜单?

解决方案

方法1:监听系统通知UIMenuController.willShowMenuNotification

当按钮的菜单即将展示时,系统会发送这个全局通知,可在控制器或视图中监听它,触发文本框失焦逻辑:

// 在viewDidLoad中注册监听
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(handleMenuWillShow), name: UIMenuController.willShowMenuNotification, object: nil)
}

// 通知处理方法
@objc private func handleMenuWillShow() {
    // 单个文本框失焦
    targetTextField.resignFirstResponder()
    // 批量处理所有文本框
    // view.subviews.compactMap { $0 as? UITextField }.forEach { $0.resignFirstResponder() }
}

// 销毁时移除监听
deinit {
    NotificationCenter.default.removeObserver(self)
}

方法2:自定义UIButton子类,重写showMenu()方法

因为showMenuAsPrimaryAction = true时,点击按钮会直接调用showMenu(),重写该方法可在菜单展示前插入自定义逻辑:

class MenuTriggerButton: UIButton {
    override func showMenu(from sourceView: UIView?, rect: CGRect) {
        // 先让文本框失焦
        UIApplication.shared.sendAction(#selector(UITextField.resignFirstResponder), to: nil, from: nil, for: nil)
        // 再调用父类方法展示菜单
        super.showMenu(from: sourceView, rect: rect)
    }
}

使用时将按钮类型替换为这个自定义类即可。

方法3:绑定按钮touchDown事件

showMenuAsPrimaryAction会接管点击逻辑,但touchDown事件仍会触发,可利用这个时机提前处理:

// 按钮配置阶段添加事件绑定
menuButton.addTarget(self, action: #selector(handleButtonTouchDown), for: .touchDown)

// 事件处理方法
@objc private func handleButtonTouchDown() {
    targetTextField.resignFirstResponder()
}

注意:该方法会在手指按下时立即触发,比菜单展示时机更早,若需精准匹配菜单即将展示的时机,前两种方法更合适。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 23:54:55