24unix
24unix

Reputation: 21

CAShapeLayer disappears while moving

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

Answers (1)

koen
koen

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

Related Questions