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
相关产品推荐
相关产品推荐

