-Today's Learning Content-

  • CALayer

1. CALayer 애니메이션 적용 문제

내용정리

CAGradientLayer를 이용해서 UIView에 그라디언트를 적용했지만, UIView.animate()를 통해 뷰의 크기가 변경될 때 그라디언트가 정상적으로 애니메이션 되지 않는 문제가 발생했다.
이를 분석하고 해결해보자

1) 문제 발생

UIView의 크기를 UIView.animate(withDuration:)를 통해 변경하면, 일반적인 서브뷰들은 부드럽게 변하지만, CAGradientLayer를 적용한 경우 그라디언트의 크기가 즉시 변경되거나 갱신되지 않는 문제가 발생할 수 있다.

func updateGradient() {
    guard let gradientLayer = self.layer.sublayers?.first(where: { $0 is CAGradientLayer }) as? CAGradientLayer else { return }
    
    UIView.animate(withDuration: 0.3) {
        gradientLayer.frame = self.bounds // 애니메이션이 적용되지 않음!
    }
}

위의 메소드에서 기대한 결과는 그라디언트가 자연스럽게 크기 변화에 맞춰 애니메이션이 적용되는 것이지만, 실제 실행 결과는 그라디언트는 애니메이션 없이 크기가 즉시 변경된다.

2) 원인 파악

CAGradientLayerCALayer의 하위 클래스이며, UIView.animateUIView의 속성(frame, bounds 등)에 대해서만 애니메이션을 적용한다.

하지만 CAGradientLayer는 애니메이션을 자동으로 적용하지 않으며, UIView.animate로도 애니메이션이 동작하지 않는다.

즉, UIView.animate를 사용해 gradientLayer.frame을 변경하더라도, CAGradientLayer의 속성 변경에는 애니메이션이 적용되지 않는다.

3) 문제 해결

CAGradientLayer의 속성 변화에 애니메이션을 적용하려면 CABasicAnimation을 사용해야 한다.

// 해결 코드
func updateGradient() {
    guard let gradientLayer = self.layer.sublayers?.first(where: { $0 is CAGradientLayer }) as? CAGradientLayer else { return }
    
    let animation = CABasicAnimation(keyPath: "bounds")
    animation.fromValue = gradientLayer.bounds
    animation.toValue = self.bounds
    animation.duration = 0.3
    animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
    
    gradientLayer.add(animation, forKey: "bounds")
    gradientLayer.frame = self.bounds
}

코드 설명

  • CABasicAnimation(keyPath: "bounds")를 사용하여 bounds 속성의 변화를 애니메이션화
  • fromValue와 toValue를 설정하여 시작과 끝 크기를 지정
  • animation.duration = 0.3으로 애니메이션 지속 시간을 설정
  • gradientLayer.add(animation, forKey: "bounds")를 호출하여 애니메이션을 적용한 후, gradientLayer.frame = self.bounds로 최종 크기를 업데이트

4) 결론

✅ UIView.animate는 UIView의 속성에 대해서만 애니메이션을 적용하며, CAGradientLayer에는 적용되지 않는다.
✅ CAGradientLayer의 크기 변경을 부드럽게 애니메이션하려면 CABasicAnimation을 사용해야 한다.
✅ bounds나 frame 속성을 CABasicAnimation을 통해 변경하면, 기대한 대로 자연스러운 애니메이션이 적용된다.

앞으로 CALayer의 애니메이션을 적용할 때는 이런 점을 잘 확인하며 진행해야겠다.

-Today's Lesson Review-

그라디언트를 넣은 뷰가 예쁜데... 
profile
이유있는 코드를 쓰자!!

0개의 댓글