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

如何检测NSTextView中图片的双击事件?

检测NSTextView中双击图片并在预览打开的实现方案

核心思路

给NSTextView添加双击手势识别,通过NSLayoutManager定位点击位置对应的文本附件,提取图片后调用预览应用打开。

具体实现步骤

  • 自定义NSTextView子类,添加双击手势识别器
  • 将点击坐标转换为文本容器内的坐标,通过NSLayoutManager获取对应字符索引
  • 判断该字符是否为图片附件占位符,若是则提取NSTextAttachment和NSImage
  • 将图片保存到临时目录,通过NSWorkspace调用预览打开临时文件

代码示例

class CustomTextView: NSTextView {
    override func awakeFromNib() {
        super.awakeFromNib()
        // 添加双击手势识别器
        let doubleClickGesture = NSClickGestureRecognizer(target: self, action: #selector(handleDoubleClick(_:)))
        doubleClickGesture.numberOfClicksRequired = 2
        addGestureRecognizer(doubleClickGesture)
    }
    
    @objc private func handleDoubleClick(_ gesture: NSClickGestureRecognizer) {
        let clickLocation = gesture.location(in: self)
        guard let textContainer = textContainer else { return }
        // 转换为文本容器内的坐标
        let containerLocation = convert(clickLocation, to: textContainer)
        
        guard let layoutManager = layoutManager else { return }
        // 获取点击位置对应的字符索引
        let characterIndex = layoutManager.characterIndex(for: containerLocation, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
        
        guard let textStorage = textStorage, characterIndex < textStorage.length else { return }
        // 判断是否是图片附件占位符
        if textStorage.string[textStorage.string.index(textStorage.string.startIndex, offsetBy: characterIndex)] == NSAttachmentCharacter {
            // 获取NSTextAttachment实例
            guard let attachment = textStorage.attribute(.attachment, at: characterIndex, effectiveRange: nil) as? NSTextAttachment,
                  let image = attachment.image else { return }
            
            // 保存图片到临时目录
            let tempDir = NSTemporaryDirectory()
            let tempFilePath = tempDir.appending("temp_preview_image.png")
            let tempFileURL = URL(fileURLWithPath: tempFilePath)
            
            do {
                // 将NSImage转为PNG数据
                guard let tiffData = image.tiffRepresentation,
                      let bitmapRep = NSBitmapImageRep(data: tiffData),
                      let pngData = bitmapRep.representation(using: .png, properties: [:]) else {
                    throw NSError(domain: "ImageConversionError", code: 0, userInfo: [NSLocalizedDescriptionKey: "无法转换图片格式"])
                }
                try pngData.write(to: tempFileURL)
                
                // 调用预览打开图片
                let previewAppURL = URL(fileURLWithPath: "/Applications/Preview.app")
                try NSWorkspace.shared.open([tempFileURL], withApplicationAt: previewAppURL, configuration: .init(), completionHandler: { success, error in
                    // 可选:打开后删除临时文件
                    if success {
                        try? FileManager.default.removeItem(at: tempFileURL)
                    }
                })
            } catch {
                print("处理图片失败: \(error.localizedDescription)")
            }
        }
    }
}

注意事项

  • 若通过Storyboard/XIB创建NSTextView,需将其类改为CustomTextView
  • 可根据原图片格式调整保存时的图片类型(如JPEG)
  • 临时文件可在打开后自动删除,避免占用磁盘空间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 08:15:34