在使用swift的Mac OS X中,我想在运行时移动标签/文本框控件



已更新 -- 我现在可以使用以下代码拖动任何 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)!)));
        }
    }

希望对您有所帮助!

最新更新