Reputation: 21
CAShapeLayer disappears while moving to another monitor, but not always
Tried searching for code examples
override func draw(_ dirtyRect: NSRect)
{
//super.draw(dirtyRect)
image?.lockFocus()
print("SelectionRect::draw")
if (shapeLayerIsVisible) {
auxLayer.removeFromSuperlayer()
shapeLayer.removeFromSuperlayer()
}
//let origin = frame.origin
auxLayer = CAShapeLayer()
auxLayer.strokeColor = NSColor.white.cgColor
auxLayer.fillColor = nil
auxLayer.lineWidth = 1.0
//rectSize = CGSize(width: x2 - x1, height: y2 - y1)
let selectionRect = frame //CGRect(x: origin.x, y: origin.y, width: frame.size.width, height: frame.size.height)
let auxPath = CGMutablePath()
//print("x1: \(x1), y1: \(y1), x2: \(x2), y2: \(y2), width: \(rectSize.width), height: \(rectSize.height)")
auxPath.addRect(selectionRect)
auxLayer.path = auxPath
layer?.addSublayer(auxLayer)
shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = NSColor.black.cgColor
shapeLayer.fillColor = nil
shapeLayer.lineWidth = 1.0
shapeLayer.lineDashPattern = [5, 5]
let path = CGMutablePath()
path.addRect(selectionRect)
shapeLayer.path = path
let lineDashAnimation = CABasicAnimation(keyPath: "lineDashPhase")
lineDashAnimation.fromValue = 0
lineDashAnimation.toValue = shapeLayer.lineDashPattern?.reduce(0) { $0 + $1.intValue }
lineDashAnimation.duration = 1
lineDashAnimation.repeatCount = Float.greatestFiniteMagnitude
shapeLayer.add(lineDashAnimation, forKey: nil)
shapeLayerIsVisible = true
layer?.addSublayer(shapeLayer)
I've got an 5K iMac with two external 4K monitors (all three scaled to look like 2560x1440 if that matters). With the given code, the NSView is initialized with x: 0, y:0, width: 100, height: 100. All works well, I can drag the Windows around on all three monitors. When I moved the Layer with the mouse to a different position and than drag the window to a different monitor the Shape disappears.
Edit: I fixed it by calling draw(9 at the end of each mouseDragged()-Event and chaninging selectionRect from frame to bounds. It works, but is that a clean solution?
Upvotes: 0
Views: 104
Reputation: 5729
Don't call draw()
yourself, per Apple's documentation:
You should never call draw() directly yourself. To invalidate part of your view, and thus cause that portion to be redrawn, call the setNeedsDisplay() or setNeedsDisplay(_:) method instead.
Upvotes: 1