从 CALayer 中删除动画

问题描述 投票:0回答:1

我目前正在构建一个绘图应用程序,该应用程序应该利用 CALayer 层次结构来避免在不必要时重新绘制每个图层(例如,我想在单独的 CALayer 上渲染临时内容,例如选择内容,而不重新渲染实际绘图)。

我的问题是我找不到禁用 CALayer 隐式动画的方法。

在此示例代码中,我在鼠标位置渲染了一个+,当我移动光标时,我可以看到旧的+淡出as you can see here

class LayerViewAppKit: NSView {
    
    let myLayer = MyLayer()
    var mousePos : CGPoint!
    var trackingArea: NSTrackingArea?
    
    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        
        self.layer = myLayer
        wantsLayer = true
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        print("not implemented")
    }
    
    override func updateTrackingAreas() {
        super.updateTrackingAreas()
        
        if let trackingArea = trackingArea {
            removeTrackingArea(trackingArea)
        }
        
        let options: NSTrackingArea.Options = [.activeAlways, .mouseMoved]
        trackingArea = NSTrackingArea(rect: bounds, options: options, owner: self, userInfo: nil)
        addTrackingArea(trackingArea!)
    }
    
    override func mouseMoved(with event: NSEvent) {
        let mousePos = convert(event.locationInWindow, from: nil)
        myLayer.drawLines(at: mousePos)
    }
    
}

这是自定义层实现

class MyLayer : CALayer {
    
    var pos : CGPoint?
    
    override func draw(in ctx: CGContext) {
        
        guard let pos = pos else {return}
        
        ctx.setStrokeColor(.black)
        let vline = NSBezierPath()
        vline.move(to: .init(x: 0, y: pos.y))
        vline.line(to: .init(x: bounds.width, y: pos.y))
        vline.lineWidth = 2
        
        let hline = NSBezierPath()
        hline.move(to: .init(x: pos.x, y: 0))
        hline.line(to: .init(x: pos.x, y: bounds.height))
        hline.lineWidth = 2
        
        ctx.addPath(vline.cgPath)
        ctx.addPath(hline.cgPath)
        
        ctx.strokePath()
    }
    
    func drawLines(at pos : CGPoint){
        self.pos = pos
        setNeedsDisplay()
    }
    
}

如何从 CALayer 中删除各种动画?

我尝试将绘图代码放入以下内容中:

CATransaction.begin()
CATransaction.setDisableActions(true)
//drawing code
CATransaction.commit()

并且还在不同的地方尝试过

myLayer.removeAllAnimations()
但没有成功。

swift core-graphics calayer appkit
1个回答
0
投票

为了避免动画,您需要隐式告诉图层事务禁用所有动画,然后提交更改。

CATransaction.begin()
CATransaction.setDisableActions(true)

// Set your new values here

CATransaction.commit()
© www.soinside.com 2019 - 2024. All rights reserved.