【问题标题】:CAShapeLayer disappears while movingCAShapeLayer 在移动时消失
【发布时间】:2019-09-17 16:50:46
【问题描述】:

CAShapeLayer 在移动到另一台显示器时会消失,但并非总是如此

尝试搜索代码示例

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)

我有一台 5K iMac,带有两个外部 4K 显示器(如果重要的话,所有三个都缩放为 2560x1440)。使用给定的代码,NSView 被初始化为 x: 0, y:0, width: 100, height: 100。一切正常,我可以在所有三个监视器上拖动 Windows。当我用鼠标将图层移动到不同的位置并将窗口拖到不同的监视器时,形状消失了。

编辑:我通过在每个 mouseDragged()-Event 结束时调用 draw(9 并将 selectionRect 从框架更改为边界来修复它。它有效,但这是一个干净的解决方案吗?

【问题讨论】:

  • 不要直接调用draw(请参阅Apple 文档),而要使视图无效,请使用setNeedsDisplay
  • 谢谢@Koen,这仍然有效,感觉更像是正确的做法。
  • 很高兴为您提供帮助,欢迎来到 Stack Overflow。如果以下答案解决了您的问题,请将其标记为已接受。
  • 我没有看到将答案标记为已接受的复选标记。
  • 嗯,是的,您需要至少 15 个声望点才能接受答案,另请参见此处:stackoverflow.com/help/whats-reputation

标签: swift macos layer


【解决方案1】:

根据 Apple 的文档,不要自己打电话给 draw()

你永远不应该自己直接调用 draw()。要使视图的一部分无效,从而导致该部分被重绘,请改为调用 setNeedsDisplay() 或 setNeedsDisplay(_:) 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-30
    相关资源
    最近更新 更多