PDFView上下文菜单事件处理:实现高亮颜色修改与移除
解决PDFView默认上下文菜单高亮编辑失效问题
你的问题核心是PDFView默认弹出的上下文菜单中,「移除高亮」和颜色修改项仅显示但无响应——这是因为这些菜单项默认没有绑定对应的处理逻辑到你的代码中,需要手动实现action方法并关联到菜单。
以下是具体实现步骤:
1. 子类化PDFView
通过子类化PDFView,我们可以拦截菜单构建过程,并为目标菜单项绑定自定义处理逻辑:
import PDFKit import UIKit class CustomPDFView: PDFView { // 处理「移除高亮」操作 @objc private func handleRemoveHighlight(_ sender: Any?) { // 获取当前选中的高亮注释 guard let highlightAnnotation = currentSelection?.annotations.first(where: { $0 is PDFAnnotationHighlight }) as? PDFAnnotationHighlight else { return } // 从页面移除注释 highlightAnnotation.page?.removeAnnotation(highlightAnnotation) } // 处理高亮颜色修改 @objc private func handleChangeHighlightColor(_ sender: NSMenuItem) { guard let highlightAnnotation = currentSelection?.annotations.first(where: { $0 is PDFAnnotationHighlight }) as? PDFAnnotationHighlight, let targetColor = sender.representedObject as? UIColor else { return } // 更新高亮颜色并刷新页面 highlightAnnotation.color = targetColor highlightAnnotation.page?.setNeedsDisplay() } // 重写菜单构建方法,绑定action到自定义逻辑 override func willOpenMenu(_ menu: NSMenu, with event: NSEvent) { super.willOpenMenu(menu, with: event) // 遍历菜单找到目标项 for item in menu.items { // 绑定「移除高亮」的action if item.title == "移除高亮" { item.action = #selector(handleRemoveHighlight(_:)) item.target = self } // 处理颜色子菜单的每个选项 else if item.hasSubmenu, let colorSubmenu = item.submenu, item.title == "颜色" { for colorItem in colorSubmenu.items { colorItem.action = #selector(handleChangeHighlightColor(_:)) colorItem.target = self // 为每个颜色菜单项绑定对应的UIColor(适配中文菜单标题) switch colorItem.title { case "黄色": colorItem.representedObject = UIColor.yellow.withAlphaComponent(0.3) case "绿色": colorItem.representedObject = UIColor.green.withAlphaComponent(0.3) case "蓝色": colorItem.representedObject = UIColor.blue.withAlphaComponent(0.3) case "粉色": colorItem.representedObject = UIColor.magenta.withAlphaComponent(0.3) default: colorItem.representedObject = UIColor.yellow.withAlphaComponent(0.3) } } } } } }
2. 替换原PDFView为自定义子类
在你的视图控制器中,将原来使用的PDFView替换为CustomPDFView:
- 如果是Storyboard/XIB创建:选中PDFView,在Identity Inspector中将Class改为
CustomPDFView。 - 如果是代码创建:直接初始化
CustomPDFView替代PDFView。
补充说明
- 菜单标题会随系统语言变化,若需要适配多语言,建议使用
NSLocalizedString匹配系统菜单的本地化文本,避免硬编码标题。 - 若不想子类化PDFView,也可以在视图控制器中实现上述action方法,然后在
willOpenMenu中将菜单项的target设置为视图控制器实例。
内容的提问来源于stack exchange,提问作者Tom J
相关产品推荐
相关产品推荐

