已更新 -- 我现在可以使用以下代码拖动任何 NSTextField 控件:
ViewController.swift
class ViewController: NSViewController {
@IBAction override func mouseDragged(theEvent: NSEvent) {
let dragPoint = theEvent.locationInWindow
//var newDragLocation = NSPoint()
print( "dragPoint X,Y = (dragPoint)" )
if controlToMove != nil {
//newDragLocation = (controlToMove!.convertPoint(dragPoint, fromView: nil))
//print( "newDragLocation X,Y = (newDragLocation)" )
var cntrl_location = NSRect();
cntrl_location = controlToMove!.frame
print( "cntrl_location X,Y = (cntrl_location)" )
let previousLocation = cntrl_location
//I think this is the problem with the current dragging? - my location is not the dragPoint
//it is the dragPoint minus/plus some offset to the control frame origin???
var location = CGPoint()
location = dragPoint
var delta_x = CGFloat()
var delta_y = CGFloat()
delta_x = location.x - previousLocation.origin.x
delta_y = location.y - previousLocation.origin.y
print( "delta X,Y = (delta_x), (delta_y)" )
// move label
cntrl_location.origin = CGPointMake(location.x + delta_x, location.y + delta_y);
print( "cntrl_location.orgin = (cntrl_location.origin)" )
// save the new drag location for the next drag event
//lastDragLocation=newDragLocation
controlToMove!.frame = cntrl_location
print( "controlToMove.frame X,Y = (controlToMove?.frame)" )
lastLocation = cntrl_location.origin
}
}
但它只有一个非常小的问题:当我拖动标签或文本字段控件时,其中两个在我拖动时出现向后闪烁,第四个在我拖动时出现。它与一个出现在鼠标位置和一个出现在新的控制帧或原点位置有关,当我拖动时交替来回和第四个。我只是还不能弄清楚拖拽的正确逻辑?
我终于有一个解决方案来解决如何在Mac OS X中在视图周围拖动标签或文本字段(NSTextField(控件的问题。我已经敲定了解决方案:
在视图控制器类中创建一个属性
class ViewController: NSViewController {
var mouseDownLocation: CGPoint?
}
在覆盖鼠标关闭事件中
var mouseDownEvent: NSEvent?
@IBAction override func mouseDown(theEvent: NSEvent) {
var event_location: NSPoint!
event_location = theEvent.locationInWindow
var cntrl_id = NSTextField()
var cntrl_frame = NSRect()
var cntrl_name = String()
var cntrl_value = String()
var hit = Bool()
for view in self.view.subviews as [NSView] {
if let ct = view as? NSTextField {
cntrl_name = ct.identifier!
cntrl_id = ct
cntrl_frame = ct.frame
cntrl_value = ct.stringValue
hit = cntrl_frame.contains(event_location)
if hit {
controlToMove = cntrl_id
lastLocation = controlToMove?.frame.origin
break
}
}
}
//figure out the difference of where the mouse went down at in the
//control frame in relation to the control frame origin
let dx = event_location.x - (controlToMove?.frame.origin.x)!
let dy = event_location.y - (controlToMove?.frame.origin.y)!
let mouseDownInCntrlFrame = CGPoint(x: dx, y: dy)
mouseDownLocation = mouseDownInCntrlFrame
}
现在在覆盖鼠标拖动事件中
@IBAction override func mouseDragged(theEvent: NSEvent) {
let dragPoint = theEvent.locationInWindow
if controlToMove != nil {
var cntrl_location = CGPoint();
cntrl_location.x = controlToMove!.frame.origin.x
cntrl_location.y = controlToMove!.frame.origin.y
print( "cntrl_location X,Y = (cntrl_location)" )
let previousLocation = cntrl_location
var location = CGPoint()
location = dragPoint
location.x -= (mouseDownLocation?.x)!
location.y -= (mouseDownLocation?.y)!
var delta_x = CGFloat()
var delta_y = CGFloat()
delta_x = location.x - previousLocation.x
delta_y = location.y - previousLocation.y
// move label
cntrl_location = CGPointMake(location.x + delta_x, location.y + delta_y);
controlToMove!.frame.origin.x = cntrl_location.x
controlToMove!.frame.origin.y = cntrl_location.y
}
}
这将允许您在视图周围拖动任何NSTextField,然后单击并拖动。它并不像我希望的那样流畅,当您在视图中拖动它时,对控件只有一点希望。但是考虑到互联网上没有关于如何拖动OS X控件的其他信息(有几个博客和有关如何拖动图像的信息 - 但即使是那些也更像是拖放类型的解决方案(在视图中快速这是一个有效的解决方案。我相信经验丰富的OS X Xcode大师可以改进此解决方案 - 如果一些有经验的OS X开发人员希望做出贡献,我欢迎对此解决方案进行改进。
感谢您的代码!它帮助了我。
我遇到了你说的同样的问题,移动的元素反弹。我怀疑这是因为 mouseDragged 被调用了几次,并且您得到了一个原始位置,在计算新位置时,它可能已经更改了。
我使用单行(以避免 mouseDragged 调用之间的冲突(并使用调用 mouseDown 时的元素位置来重建 move 方法。
当然,这不是最好的方法,它只是消除弹跳问题的替代方法。
override func mouseDragged(with event: NSEvent) {
let dragPoint = event.locationInWindow
if controlToMove != nil {
controlToMove!.setFrameOrigin(NSPoint(x: (lastLocation?.x)! + (dragPoint.x - (mouseDownLocation?.x)!), y: (lastLocation?.y)! + (dragPoint.y - (mouseDownLocation?.y)!)));
}
}
希望对您有所帮助!