2016-09-03 47 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

很高興幫助:) –