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

选中UIMenuItem时能否阻止UIMenuController自动收起?

UIMenuController点击菜单项后保持展开的实现方案

可以通过iOS公有API实现该效果,完全符合App Store审核规则,无需调用私有接口。

实现原理

UIMenuController默认的自动收起逻辑,是在菜单项绑定的action方法执行完成后,系统自动触发隐藏操作。只要在自定义的菜单项action方法执行结束前,主动调用setMenuVisible:animated:方法将菜单重新设置为显示状态,就能覆盖系统的默认隐藏行为。

具体实现步骤

  • 首先自定义需要保持菜单展开的UIMenuItem,绑定自定义响应方法
// 示例:添加缩进菜单项
UIMenuItem *indentItem = [[UIMenuItem alloc] initWithTitle:@"缩进" action:@selector(increaseIndent:)];
[UIMenuController sharedMenuController].menuItems = @[indentItem];
  • 在自定义响应方法中,业务逻辑执行完成后主动唤起菜单
- (void)increaseIndent:(UIMenuItem *)sender {
    // 执行业务逻辑,如调整文本缩进
    [self adjustTextIndent];
    
    // 若操作后文本选中区域发生变化,需重新设置菜单位置
    CGRect newSelectionRect = [self currentSelectionRect];
    [[UIMenuController sharedMenuController] setTargetRect:newSelectionRect inView:self];
    
    // 主动设置菜单为显示状态,覆盖系统默认隐藏逻辑
    [[UIMenuController sharedMenuController] setMenuVisible:YES animated:NO];
}

Swift 对应实现:

// 添加缩进菜单项
let indentItem = UIMenuItem(title: "缩进", action: #selector(increaseIndent(_:)))
UIMenuController.shared.menuItems = [indentItem]

// 响应方法实现
@objc func increaseIndent(_ sender: UIMenuItem) {
    // 执行业务逻辑
    adjustTextIndent()
    
    // 选中区域变化时重新定位菜单
    let newSelectionRect = currentSelectionRect()
    UIMenuController.shared.setTargetRect(newSelectionRect, in: self)
    
    // 保持菜单显示
    UIMenuController.shared.setMenuVisible(true, animated: false)
}

注意事项

  • 执行操作后需确保持有菜单的视图仍然保持第一响应者状态,第一响应者变更会导致菜单被系统自动收回
  • 若操作未改变选中区域的位置和大小,可以跳过重新设置targetRect的步骤
  • 上述用到的所有API从iOS 3.0开始就属于公开接口,不存在审核风险,备忘录等系统应用的对应逻辑也是基于该方案实现的

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:48:04