Swift 如何在Cocoa中的NSView中移动NSImageView?

Swift 如何在Cocoa中的NSView中移动NSImageView?,swift,cocoa,nsview,nsimageview,nsevent,Swift,Cocoa,Nsview,Nsimageview,Nsevent,在我的Mac OS应用程序中,在NSImageView中发生鼠标下降事件(由用户触发)后,我需要一种能够在NSView中移动NSImageView的功能。当用户触发鼠标上升事件时,此视图必须移动到最后一个mouseDrag事件方向并保持不变。在移动过程中,我希望NSImageView在屏幕上可见(它应该随着鼠标光标移动) 我读过苹果公司的鼠标事件处理指南, 我还下载了以下示例代码: 两个链接都包含Objective C中的代码。DragItemAround的代码已过时。我试图在GitHub和其他

在我的Mac OS应用程序中,在NSImageView中发生鼠标下降事件(由用户触发)后,我需要一种能够在NSView中移动NSImageView的功能。当用户触发鼠标上升事件时,此视图必须移动到最后一个mouseDrag事件方向并保持不变。在移动过程中,我希望NSImageView在屏幕上可见(它应该随着鼠标光标移动)

我读过苹果公司的鼠标事件处理指南, 我还下载了以下示例代码:

两个链接都包含Objective C中的代码。DragItemAround的代码已过时。我试图在GitHub和其他StackOverflow线程上搜索解决方案,但没有找到任何有效的解决方案

我很高兴听到关于这个问题的答案。我用的是Swift 3

我创建了一个自定义MovableMageView,它是NSImageView的一个子类,代码如下:

import Cocoa

class MovableImageView: NSImageView {

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
        // setup the starting location of the
        // draggable item

    }

    override func mouseDown(with event: NSEvent) {
        Swift.print("mouseDown")

        //let window = self.window!
        //let startingPoint = event.locationInWindow


    }


    override func mouseDragged(with event: NSEvent) {
        Swift.print("mouseDragged")

        self.backgroundColor = NSColor.black

    }

    override func mouseUp(with event: NSEvent) {
        Swift.print("mouseUp")
    }

}
之后,在Interface Builder中,我将该类设置为NSImageView。我还在Interface Builder中为此NSImageView设置了约束


现在我想知道如何在NSView中移动NSImageView?(Swift 3,XCode 8)

您需要保存鼠标下降点,并在以后用于偏移。请检查以下代码:

class MovableImageView: NSImageView {

var firstMouseDownPoint: NSPoint = NSZeroPoint

init() {
    super.init(frame: NSZeroRect)
    self.wantsLayer = true
    self.layer?.backgroundColor = NSColor.red.cgColor
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

override func draw(_ dirtyRect: NSRect) {
    super.draw(dirtyRect)

    // Drawing code here.
}

override func mouseDown(with event: NSEvent) {
    Swift.print("mouseDown")
    firstMouseDownPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))!
}

override func mouseDragged(with event: NSEvent) {
    Swift.print("mouseDragged")
    let newPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))!
    let offset = NSPoint(x: newPoint.x - firstMouseDownPoint.x, y: newPoint.y - firstMouseDownPoint.y)
    let origin = self.frame.origin
    let size = self.frame.size
    self.frame = NSRect(x: origin.x + offset.x, y: origin.y + offset.y, width: size.width, height: size.height)
}

override func mouseUp(with event: NSEvent) {
    Swift.print("mouseUp")

    }
}
在父视图中,只需将此MovableMageView添加为子视图,如下所示:

let view = MovableImageView()
view.frame = NSRect(x: 0, y: 0, width: 100, height: 100)
self.view.addSubview(view) //Self is your parent view

@brianlikeaple答案的约束版本:

class MovableImageView: NSImageView {

var firstMouseDownPoint: NSPoint = NSZeroPoint
var xConstraint: NSLayoutConstraint!
var yContstraint: NSLayoutConstraint!

required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
    self.wantsLayer = true
    self.layer?.backgroundColor = NSColor.red.cgColor
}
override func draw(_ dirtyRect: NSRect) {
    super.draw(dirtyRect)
    
    // Drawing code here.
}

override func mouseDown(with event: NSEvent) {
    Swift.print("mouseDown")
    firstMouseDownPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))!
}

override func mouseDragged(with event: NSEvent) {
    Swift.print("mouseDragged")
    let newPoint = (self.window?.contentView?.convert(event.locationInWindow, to: self))!
    let offset = NSPoint(x: newPoint.x - firstMouseDownPoint.x, y: newPoint.y - firstMouseDownPoint.y)
    let origin = self.frame.origin
    let size = self.frame.size
    yContstraint.constant = (self.superview?.frame.height)! - origin.y - offset.y - size.height
    xConstraint.constant = origin.x + offset.x
}

override func mouseUp(with event: NSEvent) {
    Swift.print("mouseUp")
    
}

你把一个错误的生物分类了。改为子类NSView。@ElTomato否,NSImageVIew是NSControl的子类,NSControl是NSView的子类。所以这应该没问题,这太傻了。Adelmaer说,他或她有一个NSView容器,其中包含一个或多个要用鼠标指针重新定位的对象。在这种情况下,您应该子类化NSView。@ElTomato NSImageView最终从NSView继承,将NSImageView放在NSView中是非常常见的OOP。怎么了?