2016-09-03 44 views
2

有一个NSImageView的子类,CALayer的实例被创建,所以我们在图像上看到一个矩形。问题是如何在鼠标关闭时(当鼠标指针位于矩形内时)移动此矩形并拖动。当鼠标向上时,这个矩形(CALayer)应该保持在图像上的新位置。如何在NSImageView上移动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 

    } 
}  
+0

我会建议显示你到目前为止所做的代码。 –

+0

@Jeshua Lacock我添加了一个示例 – VYT

+0

鼠标事件在哪里? https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html –

回答

3

你很接近你的目标,只实现鼠标事件!

这里是一个工作片段:


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; 

     } 

    } 

} 

输出会是这样的(没有BG图像已被设置虽然


Before dragging After dragging

你甚至可以添加转场效果,边框,渐变和其它更多!

CALayers和更一般的CoreAnimation真的很强大!

请让我知道你是否需要澄清,

我希望这有助于,如果是的话标志着这个答案是正确的,以便其他人可以使用它!

干杯。

+0

感谢您的好评!这是一个很好的教学方法的例子! – VYT

+0

很高兴帮助:) –