Home > Software engineering >  CATransition type fade seems broken
CATransition type fade seems broken

Time:10-19

When working on this question, I notice that maybe fade of CATransitionType in CATransition is not working or broken. The rest of CATransitionType: moveIn, push, reveal works correctly.

I'm working on iPhone 13, iOS 16.0.

Code of the transition:

extension CALayer {
    func makeFadeTransition() {
        let transition = CATransition()
        transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        transition.duration = 0.5
        transition.type = .fade
        self.add(transition, forKey: nil)
    }
}

Usage:

self.customView.layer.makeFadeTransition()

I know that we can switch to using UIView.animate combined with alpha to change opacity instead.

UIView.animate(withDuration: 0.15, animations: {
    self.customView.alpha = 0.0
})

or using CABasicAnimation:

extension CALayer {
    func makeFadeTransition() {
        let transition = CABasicAnimation(keyPath: "opacity")
        transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        transition.duration = 0.5
        transition.fromValue = 1.0
        transition.toValue = 0.0
        self.add(transition, forKey: nil)
    }
}

But again, is CATransitionType type fade broken, or am I wrong at something? Thanks in advanced.

CodePudding user response:

You have to do something to change the layer...

For example, to fade-out / fade-in, we could do this:

extension CALayer {
    func makeFadeTransition() {

        let transition = CATransition()
        transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        // let's use duration of 2.5 to make it more obvious
        transition.duration = 2.5
        transition.type = .fade
        
        // change the layer... opacity, backgroundColor, frame, etc
        
        // fade transition doesn't like opacity of 0.0, so we'll use 0.01
        self.opacity = self.opacity == 1.0 ? 0.01 : 1.0
        
        // or, for example,
        // "shrink" the layer by 20-points
        //self.frame = self.frame.insetBy(dx: 20.0, dy: 20.0)
    
        self.add(transition, forKey: nil)
        
    }
}
  • Related