如何在 NSImageView 上移动 CALayer
How to move CALayer on 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({ [=10=].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)
您甚至可以添加过渡效果、边框、渐变等等!
CALayers 和更一般的 CoreAnimation 真的很强大!
如果您需要说明,请告诉我,
希望对您有所帮助,如果有帮助,请将此答案标记为正确,以便其他人可以使用!
干杯。
有一个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({ [=10=].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)
您甚至可以添加过渡效果、边框、渐变等等!
CALayers 和更一般的 CoreAnimation 真的很强大!
如果您需要说明,请告诉我,
希望对您有所帮助,如果有帮助,请将此答案标记为正确,以便其他人可以使用!
干杯。