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

iOS 16下如何正确获取UIMenuController的菜单位置?

iOS 16 下获取 WKWebView 菜单位置的正确方法

在 iOS 13 里,我们可以用这段代码拿到 WKWebView 上下文菜单的位置:

let menuFrame = UIMenuController.shared.menuFrame

但到了 iOS 16,UIMenuController 被弃用了,再调用 menuFrame 只会返回 zero,完全拿不到有效位置。这里给你两个可行的替代方案:

1. 自定义菜单用 UIContextMenuInteraction 监听

如果是你自己给 WKWebView 加的自定义上下文菜单,直接用 UIContextMenuInteraction 的代理方法就能拿到准确位置:
实现 contextMenuInteraction(_:willDisplayMenu:forConfiguration:animator:) 这个代理方法,菜单即将显示时,通过 menu.preferredFrame 获取它的位置。示例代码如下:

func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willDisplayMenu menu: UIMenu, for configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionAnimating?) {
    let menuFrame = menu.preferredFrame
    // 在这里使用菜单的位置信息
}

2. 系统默认菜单的间接估算方法

如果是 WKWebView 自带的系统上下文菜单,没法直接通过新 API 拿到位置,只能通过文本选中区域间接估算:
先注册 UIMenuController.menuDidShowNotification 通知,菜单弹出后,通过 WKWebView 的 selectedTextRange 获取选中文本的矩形区域,菜单一般会显示在这个区域的上方或下方,以此推算大致位置。示例代码:

// 先注册通知
NotificationCenter.default.addObserver(self, selector: #selector(handleMenuDidShow), name: UIMenuController.menuDidShowNotification, object: nil)

@objc private func handleMenuDidShow() {
    guard let selectedRange = webView.selectedTextRange,
          let textRect = webView.firstRect(for: selectedRange) else { return }
    // 菜单通常在文本区域上方,这里以向上偏移60pt为例,高度按44pt计算(可根据实际调整)
    let estimatedMenuFrame = CGRect(x: textRect.origin.x, y: textRect.origin.y - 60, width: textRect.width, height: 44)
    // 使用这个估算的位置
}

注意,第二种方法是间接估算,不同设备或系统版本可能有偏差,如果能用自定义菜单的方案,优先选第一种。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:22:18