본문 바로가기

IOS Swift

[iOS+2] CALayer 알아보기 (shadow, gradient, animation)

목차

  1.  CALayer란?
  2. CALayer 구조
  3.  CALayer 사용 예제

UIView를 다룰 때 layer를 한 번쯤은 보셨을 겁니다.

최근에 복잡한 Custom UI를 개발해야해서 (그라디언트 + 그림자 + 애니메이션 + 모서리 둥글게)

CALayer에 대해서 학습해보았습니다.

 

1. CALayer란?

An object that manages image-based content and allows you to perform animations on that content.
시각적 콘텐츠 관리 및 애니메이션화를 위한 인터페이스를 제공하는 Core Animation 프레임워크의 기본 클래스

 

생소한 거 또 나왔다.
Core Animation 프레임워크..?

 

1-1.  Core Animation 

Core Animation is a graphics rendering and animation infrastructure available on both iOS and OS X that you use to animate the views and other visual elements of your app.
코어 애니메이션은 iOS 및 OS X 모두에서 앱의 view와 다른 시각적 요소의 애니메이션을 할 수 있는 그래픽 렌더링 및 애니메이션 인프라입니다. 

 

iOS 앱을 작성하고 있다면 알든 모르든 Core Animation을 사용하고 있습니다

 Core Animation을 사용하면 애니메이션의 각 프레임을 그리는 데 필요한 대부분의 작업이 자동으로 수행됩니다. Core Animation이 나머지는 대부분의 실제 드로잉 작업을 온보드 그래픽 하드웨어에 넘겨 렌더링을 가속화합니다. 이 자동 그래픽 가속은 CPU에 부담을 주지 않고 앱 속도를 저하시키지 않으면서 높은 프레임 속도와 부드러운 애니메이션을 제공합니다.
(대부분의 레이어는 앱에서 실제 그리기를 수행하지 않는다고 합니다. 앱이 제공하는 콘텐츠를 비트맵에 캐싱하고 해당 레이어를 변경하면 관련된 상태 정보만 변경된다고 합니다.) <Core Animation이 컨텐츠를 그리는 방법>

Core Animation의 구조

저희가 주로 사용하는 High Level의 UIKit 모듈은 Low Level의 Core Animation을 사용하고 있네요. 

view.backgroundColor = .blue

Apple이 추상화해준 덕분에 이렇게 간단하게 백그라운드의 색을 줄 수 있던 것이었습니다. 👍

 


 

2. CALayer 구조

Layer의 구조는 UIView의 계층구조와 비슷합니다. 하나의 Layer 안에 다른 여러 Layer가 들어갈 수 있습니다.

 

3. CALayer 사용 예제

3-1. 그림자 그리기

  1. View Shadow 관련 속성 사용하는 방법
  2. CALayer 만들어서 사용하는 방법

 

< View Shadow 관련 속성 사용하는 방법 > 

  • View는 Layer와 달리 터치 이벤트와 같은 이벤트를 받을 수 있습니다.
  • View의 Shadow는 View의 크기에 따라 동적으로 변합니다.

 

< CALayer 사용하는 방법 > 

CALayer를 애니메이션 하기 위해선 CABasicAnimation와 같은 코드를 추가 작성해주어야 합니다. (View와 달리 레이어는 자체 모양을 정의하지 않습니다. 레이어는 단순히 비트맵을 둘러싼 상태 정보를 관리합니다. 비트맵 자체는 뷰 드로잉 자체의 결과이거나 고정 이미지일 수 있습니다.)

- 코드 -

더보기

 

class ViewController: UIViewController {
    
    let testView = UIView(frame: .init(x: 50, y: 100, width: 200, height: 200))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(testView)
        addShadow()
        UIView.animate(withDuration: 8.0) { [unowned self] in
            testView.frame = CGRect(x: 50, y: 100, width: 300, height: 500)
        }
    }
    
    // UIView에 있는 property를 통해 사용
    func addShadow() {
        testView.layer.borderWidth = 2
        testView.layer.borderColor = UIColor.blue.cgColor
        testView.layer.shadowColor = UIColor.black.cgColor
        testView.layer.shadowOpacity = 1
        testView.layer.shadowOffset = CGSize(width: 10, height: 10)
        testView.layer.shadowRadius = 2
    }
  
    // Layer 만들어서 사용
    func addShadow() {
        let shadowLayer = CAShapeLayer()
        shadowLayer.frame = testView.bounds
        shadowLayer.borderWidth = 2
        shadowLayer.borderColor = UIColor.blue.cgColor
        shadowLayer.shadowColor = UIColor.black.cgColor
        shadowLayer.shadowOpacity = 1
        shadowLayer.shadowOffset = CGSize(width: 10, height: 10)
        shadowLayer.shadowRadius = 2
        testView.layer.addSublayer(shadowLayer)
    }
}

 

 

3-2. 그라디언트 그리기

class ViewController: UIViewController {
    let testView = UIView(frame: .init(x: 50, y: 100, width: 200, height: 200))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(testView)
        addGradient()
    }

    func addGradient() {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = testView.bounds
        gradientLayer.colors = [UIColor.green.cgColor, UIColor.yellow.cgColor]
        gradientLayer.borderWidth = 1
        gradientLayer.borderColor = UIColor.black.cgColor
        testView.layer.addSublayer(gradientLayer)
    }
}

 

3-3.Shadow Layer + Gradient Layer + Animation

class ViewController: UIViewController {
    
    let testView = UIView(frame: .init(x: 50, y: 100, width: 200, height: 200))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.view.addSubview(testView)
        addShadow()
        addGradient()
    }
    
    func addShadow() {
        testView.layer.shadowColor = UIColor.black.cgColor
        testView.layer.shadowOpacity = 1
        testView.layer.shadowOffset = CGSize(width: 10, height: 10)
        testView.layer.shadowRadius = 2
    }

    func addGradient() {
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = testView.bounds
        gradientLayer.colors = [UIColor.green.cgColor, UIColor.yellow.cgColor]
        gradientLayer.borderWidth = 1
        gradientLayer.borderColor = UIColor.black.cgColor
        testView.layer.addSublayer(gradientLayer)

         let animation = CABasicAnimation(keyPath: "bounds.size.height")
         animation.fromValue = gradientLayer.bounds.height
         animation.toValue = gradientLayer.bounds.height * 2
         animation.duration = 2.0
         animation.autoreverses = true
         animation.repeatCount = .infinity

         gradientLayer.add(animation, forKey: "bounds.size.height")
    }
}

 

 

 참고

 

 

반응형