【问题标题】:How to move NSImageView inside NSView in Cocoa?如何在 Cocoa 的 NSView 中移动 NSImageView?
【发布时间】:2017-09-07 13:03:20
【问题描述】:

在我的 Mac OS 应用程序中,我需要一个能够在此 NSImageView 中发生 mouseDown 事件(由用户触发)后在 NSView 内移动 NSImageView 的功能。当用户触发 mouse Up 事件时,该视图必须移动到最后一个 mouseDrag 事件方向并停留在那里。在移动过程中,我希望 NSImageView 在屏幕上可见(它应该与鼠标光标一起移动)。

我已阅读 Apple 的处理鼠标事件指南,https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html 我也下载了这个示例代码:https://developer.apple.com/library/content/samplecode/DragItemAround/Introduction/Intro.html

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

很高兴听到这个问题的答案。我正在使用 Swift 3。

我创建了一个自定义的 MovableImageView,它是 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? (斯威夫特 3,XCode 8)

【问题讨论】:

  • 你继承了一个错误的生物。改为子类 NSView。
  • @ElTomato 不,NSImageVIew 是 NSControl 的子类,它是 NSView 的子类。所以这应该没问题。

标签: swift cocoa nsview nsimageview nsevent


【解决方案1】:

您需要保存 mouseDown 点并稍后将其用于偏移。请检查以下代码:

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")

    }
}

在父视图中,只需将这个 MovableImageView 添加为子视图,如下所示:

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

【讨论】:

  • 这很愚蠢。 Adelmaer 说他或她有一个 NSView 容器,其中包含一个或多个对象,可以用鼠标指针重新定位。在这种情况下,您应该继承 NSView。
  • @ElTomato NSImageView 最终继承自 NSView 并将 NSImageView 放入 NSView 是很常见的 OOP。它有什么问题?
【解决方案2】:

@brianLikeApple 回答的约束版本:

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")
    
}

【讨论】:

    猜你喜欢
    • 2014-07-29
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    相关资源
    最近更新 更多