Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

Subclassing CALayer breaks animations

Trying to do a simple opacity fade in/out over 1.5 seconds. (0.5 seconds in, 1s out).

If I add a generic CAShapeLayer to a UIView and do all my drawing there it works.

If I subclass CAShapeLayer and do my drawing there, the CATranscation.setAnimationDuration(_:) block does not respect the duration and executes quickly. Additionally, sometimes it inverts the opacity!

Implementation 1: Draw directly from inside view

class Implemention1: UIView {
    
    let shapeLayer = CAShapeLayer()
        
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.setup()
    }
    
    func setup() {
        self.layer.insertSublayer(self.shapeLayer, at: 0)
        self.shapeLayer.opacity = 0
        self.shapeLayer.fillColor = UIColor.red.cgColor
        self.shapeLayer.frame = self.bounds
        self.shapeLayer.path = UIBezierPath(rect: self.bounds).cgPath
    }
    
    func fadeOpacticityInOut() {
        CATransaction.begin()
        CATransaction.setAnimationDuration(0.5)
        CATransaction.setCompletionBlock {
            CATransaction.begin()
            CATransaction.setAnimationDuration(1.0)
            self.shapeLayer.opacity = 0
            CATransaction.commit()
        }
        self.shapeLayer.opacity = 1
        CATransaction.commit()
    }
}    

Implementation 2: Subclassing CAShapeLayer and doing more or less the same thing.

class Implementation2: UIView {
    
    let shapeLayer = FadeLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.setup()
    }
    
    func setup() {
        self.layer.insertSublayer(self.shapeLayer, at: 0)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        self.shapeLayer.frame = self.bounds
        self.shapeLayer.setNeedsDisplay()
    }
    
    
    func fadeOpactiyInOut() {
        self.shapeLayer.fadeOpacticityInOut()
    }
    
}

class FadeLayer: CAShapeLayer {
    
    override init(layer: Any) {
        super.init(layer: layer)
        self.setup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        self.setup()
    }
    
    override init() {
        super.init()
        self.setup()
    }
    
    func setup() {
        self.opacity = 0
        self.fillColor = UIColor.red.cgColor
    }
    
    func fadeOpacticityInOut() {
        CATransaction.begin()
        CATransaction.setAnimationDuration(0.5)
        CATransaction.setCompletionBlock {
            CATransaction.begin()
            CATransaction.setAnimationDuration(1.0)
            self.opacity = 0
            CATransaction.commit()
        }
        self.opacity = 1
        CATransaction.commit()
    }
    
    override func display() {
        self.path = UIBezierPath(rect: self.bounds).cgPath
    }

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...