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

如何检测UIMenu被dismiss(关闭)的时机

监听UIMenu关闭的可用方案

方案1:使用 Context Menu Interaction 代理(适配iOS14+,覆盖所有UIMenu触发场景)

不管你是将UIMenu绑定为长按触发还是点击触发(showsMenuAsPrimaryAction = YES),都可以通过实现UIContextMenuInteractionDelegate的结束回调来监听关闭事件:

  • 首先给你的UIButton绑定菜单并添加交互代理:
// Objective-C 示例
self.button.showsMenuAsPrimaryAction = YES;
self.button.menu = [UIMenu menuWithChildren:@[/* 你的菜单选项 */]];
[self.button addInteraction:[UIContextMenuInteraction interactionWithDelegate:self]];
// Swift 示例
button.showsMenuAsPrimaryAction = true
button.menu = UIMenu(children: [/* 你的菜单选项 */])
button.addInteraction(UIContextMenuInteraction(delegate: self))
  • 然后实现代理的结束方法,这里就是菜单关闭的触发时机:
- (void)contextMenuInteraction:(UIContextMenuInteraction *)interaction willEndForConfiguration:(UIContextMenuConfiguration *)configuration animator:(id<UIContextMenuInteractionAnimating>)animator {
    // 菜单即将关闭,在这里执行移除按钮的逻辑
    [self.button removeFromSuperview];
}
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willEndFor configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) {
    // 菜单即将关闭,执行移除按钮逻辑
    button.removeFromSuperview()
}

注意:这个方法不管用户是点击菜单外部区域关闭,还是点击菜单项后自动关闭都会触发,完全匹配需求。


方案2:iOS16+ 极简方案

如果你的App最低支持iOS16,可以直接使用UIButton新增的menuPresentationDelegate回调监听关闭事件:

button.menuPresentationDelegate = self

// 实现代理方法
func menuPresentationControllerDidDismiss(_ controller: UIMenuPresentationController) {
    // 菜单已经关闭,执行对应逻辑
    button.removeFromSuperview()
}

避坑提示

  • 不要尝试监听私有通知或者私有类的生命周期,后续系统版本迭代很容易失效
  • 上述两个方案都不需要监听菜单弹出事件,只会在关闭时触发回调

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:24:04