拖放NSImageView Swift MacOS应用程序中渲染的动画GIF
我正在尝试构建一个MacOSX应用程序,它可以呈现多个GIF,并允许用户拖放它们,以便将GIF复制到其他应用程序中。我正在使用符合拖放NSImageView Swift MacOS应用程序中渲染的动画GIF,swift,macos,swiftui,gif,Swift,Macos,Swiftui,Gif,我正在尝试构建一个MacOSX应用程序,它可以呈现多个GIF,并允许用户拖放它们,以便将GIF复制到其他应用程序中。我正在使用符合NSImageView的DragDropImageView(下面的代码)来渲染启用拖放功能的gif 它工作正常,只是当我将gif拖放到另一个应用程序中时,它只复制gif的一个图像帧。我的目的是复制整个gif文件,而不仅仅是一个图像 一般来说,我对iOS/MacOS的开发相当陌生,我不确定构建这个可拖动gif组件的方法是否正确 我正在使用swiftUI构建应用程序,我使
NSImageView
的DragDropImageView
(下面的代码)来渲染启用拖放功能的gif
它工作正常,只是当我将gif拖放到另一个应用程序中时,它只复制gif的一个图像帧。我的目的是复制整个gif文件,而不仅仅是一个图像
一般来说,我对iOS/MacOS的开发相当陌生,我不确定构建这个可拖动gif组件的方法是否正确
我正在使用swiftUI构建应用程序,我使用一个名为GifImageView
的自定义视图,该视图将DragDropImageView
转换为swiftUI视图
DragDropImageView.swift
import Cocoa
class DragDropImageView: NSImageView, NSDraggingSource {
/// Holds the last mouse down event, to track the drag distance.
var mouseDownEvent: NSEvent?
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
isEditable = false
}
required init?(coder: NSCoder) {
super.init(coder: coder)
// Assure editable is set to true, to enable drop capabilities.
isEditable = true
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
}
// MARK: - NSDraggingSource
// Since we only want to copy the current image we register
// for .Copy operation.
func draggingSession(_: NSDraggingSession,
sourceOperationMaskFor _: NSDraggingContext) -> NSDragOperation {
return NSDragOperation.copy
}
// // Clear the ImageView on delete operation; e.g. the image gets
// // dropped on the trash can in the dock.
// func draggingSession(_: NSDraggingSession, endedAt _: NSPoint,
// operation: NSDragOperation) {
// if operation == .delete {
// image = nil
// }
// }
// Track mouse down events and safe the to the poperty.
override func mouseDown(with theEvent: NSEvent) {
mouseDownEvent = theEvent
}
// Track mouse dragged events to handle dragging sessions.
override func mouseDragged(with event: NSEvent) {
// Calculate the dragging distance...
let mouseDown = mouseDownEvent!.locationInWindow
let dragPoint = event.locationInWindow
let dragDistance = hypot(mouseDown.x - dragPoint.x, mouseDown.y - dragPoint.y)
// Cancel the dragging session in case of an accidental drag.
if dragDistance < 3 {
return
}
guard let image = self.image else {
return
}
let draggingImage = image
// Create a new NSDraggingItem with the image as content.
let draggingItem = NSDraggingItem(pasteboardWriter: image)
// Calculate the mouseDown location from the window's coordinate system to the
// ImageView's coordinate system, to use it as origin for the dragging frame.
let draggingFrameOrigin = convert(mouseDown, from: nil)
// Build the dragging frame and offset it by half the image size on each axis
// to center the mouse cursor within the dragging frame.
let draggingFrame = NSRect(origin: draggingFrameOrigin, size: draggingImage.size)
.offsetBy(dx: -draggingImage.size.width / 2, dy: -draggingImage.size.height / 2)
// Assign the dragging frame to the draggingFrame property of our dragging item.
draggingItem.draggingFrame = draggingFrame
// Provide the components of the dragging image.
draggingItem.imageComponentsProvider = {
let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon)
component.contents = image
component.frame = NSRect(origin: NSPoint(), size: draggingFrame.size)
return [component]
}
// Begin actual dragging session. Woohow!
beginDraggingSession(with: [draggingItem], event: mouseDownEvent!, source: self)
}
}
import AppKit;
import SwiftUI;
struct GifImageView: NSViewRepresentable {
var image: NSImage
func makeNSView(context: Context) -> DragDropImageView {
let view = DragDropImageView()
view.image = self.image
// view.allowsCutCopyPaste = true
return view
}
func updateNSView(_ view: DragDropImageView, context: Context) {
}
}
struct GifImageView_Previews: PreviewProvider {
static var previews: some View {
GifImageView(image: NSImage(data: (NSDataAsset(name: "tenor")?.data)!)!)
}
}
在我的ContentView.swift
中,我使用我的GifImageView
如下:
GifImageView(image: *some NSImage*)
请原谅,我注意到的是拖放,我将在大约一周后用我的应用程序处理它。通读你的问题?两次(包括问题标题)说明MacOS,但两次(包括标签)说明iOS。我认为它的标签不正确。您的代码有
include cococoa
和include AppKit
,这表明(对我来说)您不是talk iOS(即UIKit
)。最后一件事-你说的是动画GIF吗?是的,我指的是动画GIF。谢谢你的建议。我已经相应地编辑了我的问题。问题是您的拖动会获取图像视图的图像
。但这不是动画gif。它只是一帧动画gif。如果要拖放动画gif,需要检索原始文件。该文件是动画gif。但即使在调用myGifImageView
时,我也会将gif作为NSImage
传递给它,它也能正确播放gif。那么为什么拖动NSImage
会导致它只复制图像而不复制gif?话虽如此,我还是想试试你的建议。是否有办法拖动文件而不是图像
?我不知道从NSImage
检索文件的简单方法。请原谅,我注意到的是拖放,我将在大约一周后用我的应用程序处理这个问题。通读你的问题?两次(包括问题标题)说明MacOS,但两次(包括标签)说明iOS。我认为它的标签不正确。您的代码有include cococoa
和include AppKit
,这表明(对我来说)您不是talk iOS(即UIKit
)。最后一件事-你说的是动画GIF吗?是的,我指的是动画GIF。谢谢你的建议。我已经相应地编辑了我的问题。问题是您的拖动会获取图像视图的图像
。但这不是动画gif。它只是一帧动画gif。如果要拖放动画gif,需要检索原始文件。该文件是动画gif。但即使在调用myGifImageView
时,我也会将gif作为NSImage
传递给它,它也能正确播放gif。那么为什么拖动NSImage
会导致它只复制图像而不复制gif?话虽如此,我还是想试试你的建议。是否有办法拖动文件而不是图像
?我不知道从NSImage
检索文件的简单方法。