MacOS AppKit:NSTextView拖拽事件正常但无拖拽动画问题
解决NSTextView子类拖拽无动画问题
你的拖拽事件能正常触发但看不到动画,核心问题出在MyTextView的mouseDown方法里——设置拖拽内容时用了错误的参数:
draggingItem.setDraggingFrame(self.bounds, contents:.Publisher)
.Publisher并不是有效的拖拽内容载体,系统无法基于它生成拖拽动画。你需要生成当前MyTextView的视图快照作为拖拽内容。
修改后的MyTextView代码
class MyTextView:NSTextView, NSPasteboardItemDataProvider { func pasteboard(_ pasteboard: NSPasteboard?, item: NSPasteboardItem, provideDataForType type: NSPasteboard.PasteboardType) { NSLog ("Paste") } override func mouseDown(with theEvent: NSEvent) { let pasteboardItem = NSPasteboardItem() pasteboardItem.setDataProvider(self, forTypes: [.string]) let draggingItem = NSDraggingItem(pasteboardWriter: pasteboardItem) // 生成当前视图的快照作为拖拽内容 let snapshotBounds = self.bounds if let bitmapRep = self.bitmapImageRepForCachingDisplay(in: snapshotBounds) { self.cacheDisplay(in: snapshotBounds, to: bitmapRep) let snapshotImage = NSImage(size: snapshotBounds.size) snapshotImage.addRepresentation(bitmapRep) draggingItem.setDraggingFrame(snapshotBounds, contents: snapshotImage) } else { // 快照生成失败时的降级处理 draggingItem.setDraggingFrame(snapshotBounds, contents: NSImage(systemSymbolName: "text.bubble", accessibilityDescription: nil)) } beginDraggingSession(with: [draggingItem], event: theEvent, source: self) } override func draggingUpdated(_ sender: NSDraggingInfo) -> NSDragOperation { return NSDragOperation.copy } }
关键修改说明
- 用
bitmapImageRepForCachingDisplay+cacheDisplay生成视图精确快照,保证拖拽动画和原视图视觉一致 - 增加快照生成失败的降级逻辑,避免无拖拽内容的情况
- 保留原有拖拽事件逻辑,确保触发流程正常
额外提示
如果只需要文本拖拽的简单预览,也可以直接用NSImage绘制文本内容,但视图快照的方式更贴合原视图的视觉表现。
内容的提问来源于stack exchange,提问作者Sidharth Mahesh Nair
相关产品推荐
相关产品推荐

