swift - 如何在 NSImageView 上移动 CALayer

标签 swift calayer nsimageview

有一个NSImageView的子类,并创建了CALayer的实例,因此我们在图像上看到一个矩形。问题是当鼠标按下(当鼠标指针位于矩形内部时)并拖动时如何移动该矩形。当鼠标松开时,此矩形 (CALayer) 应保留在图像上的新位置。

例如

class ImageViewWithRectangle: NSImageView
{
    var shape : CAShapeLayer!

    func drawRectangle()
    {   
        shape = CAShapeLayer()
        shape.lineWidth = 1.0
        shape.fillColor = NSColor.clear().cgColor
        shape.strokeColor = NSColor.gray().cgColor
        shape.lineDashPattern = [1,1]
        self.layer?.addSublayer(shape)

        let path = CGMutablePath()
        path.moveTo(nil, x: 1, y: 1)
        path.addLineTo(nil, x: 1, y: 50)
        path.addLineTo(nil, x: 50, y: 50)
        path.addLineTo(nil, x: 50, y: 1)
        path.closeSubpath()
        self.shape.path = path

    }
}     

最佳答案

You are very close to your goal, just implement the mouse events !

这是一个工作片段:


class ImageViewWithRectangle: NSImageView {

    var shape : CAShapeLayer!

    var shapeRect = NSMakeRect(10, 10, 100, 50)

    var shouldMove = false;

    var anchorPoint : NSPoint!

    override func awakeFromNib() {

        //We MUST implement layers! Otherwise nothing will work!!
        //You could do it even through Interface Builder

        self.wantsLayer = true;

    }

    override func drawRect(dirtyRect: NSRect) {

        //Every time the view is drawn, remove the old layer
        self.layer?.sublayers?.forEach({ $0.removeFromSuperlayer() })

        //Draw the new one
        self.drawRectangle()
    }

    func drawRectangle()
    {

        //Draw the layer
        shape = CAShapeLayer()
        shape.lineWidth = 1.0
        shape.fillColor = NSColor(calibratedWhite: 1, alpha: 0).CGColor
        shape.strokeColor = NSColor.grayColor().CGColor
        shape.lineDashPattern = [1,1]
        shape.backgroundColor = NSColor.greenColor().CGColor

        //No need for CGPaths for a simple rect, just set the frame and fill it
        shape.frame = self.shapeRect

        self.layer?.addSublayer(shape)

    }

    //Implmenet mouse events
    override func mouseDown(theEvent: NSEvent) {

        //get coordinates
        let pos = theEvent.locationInWindow

        //Check if inside the rect
        if ((pos.x >= self.shapeRect.origin.x) && (pos.x <= self.shapeRect.origin.x + self.shapeRect.size.width)) {

            //X match, now check Y
            if ((pos.y >= self.shapeRect.origin.y) && (pos.y <= self.shapeRect.origin.y + self.shapeRect.size.height)) {

                //If we get here, then we're insisde the rect!
                self.shouldMove = true;

                //OPTIONAL : Set an anchor point
                self.anchorPoint = NSMakePoint(pos.x - self.shapeRect.origin.x, pos.y - self.shapeRect.origin.y);


            }

        }


    }

    override func mouseDragged(theEvent: NSEvent) {

        if (self.shouldMove) {

            let pos = theEvent.locationInWindow

            //Update rect origin, or whatever you want to use as anchor point
            self.shapeRect.origin = NSMakePoint(pos.x - self.anchorPoint.x, pos.y - self.anchorPoint.y)

            //Redraw the view
            self.display()

        }

    }

    override func mouseUp(theEvent: NSEvent) {

        if (self.shouldMove) {

            //Reset value
            self.shouldMove = false;

        }

    }

}

The output will be something like this (No bg images have been set though)


Before dragging After dragging

您甚至可以添加过渡效果、边框、渐变等等!

CALayers 以及更普遍的 CoreAnimation 真的很强大!

如果您需要澄清,请告诉我,

我希望这有帮助,如果有的话请将此答案标记为正确,以便其他人可以使用它!

干杯。

关于swift - 如何在 NSImageView 上移动 CALayer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39311698/

相关文章:

ios - 如何将子图层居中放置在另一图层上?

swift - 无法快速设置 NSImageView 的图像属性

cocoa - NSImage 的动画在使用 NSKeyedArchiver 存档后丢失

swift - 准备转场

ios - 使用verticalAlighment和alignmentGuide对齐 View 的底部对齐方式

ios - 动画边界更改时具有 CALayer 有线效果的自定义 View

ios - 如何在 CALayer 对象的外部添加阴影?

objective-c - NSView 子类drawRect 在无限循环中被调用

ios - 如何在同一类中使用警报和微调器?

ios - 通过 UIActivityViewController (Twitter, Facebook, Instagram) 使用主题标签分享图片