Как переместить 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
}
}
1 ответ
Вы очень близки к своей цели, просто реализуйте события мыши!
Вот рабочий фрагмент:
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;
}
}
}
Вывод будет примерно таким (хотя изображения не были установлены)
Вы даже можете добавить эффекты перехода, границы, градиенты и многое другое!
CALayers и в целом CoreAnimation действительно мощная!
Пожалуйста, дайте мне знать, если вам нужны разъяснения,
Я надеюсь, что это помогло, если это так, отметьте этот ответ как правильный, чтобы другие могли его использовать!
Приветствия.