ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Core Animation
    iOS 2021. 4. 1. 18:44

    안녕하세요. 그린입니다🟢

    이번 포스팅에서는 저번 Core Graphics에 이어 Core Animation에 대해 학습하겠습니다🧑🏻‍💻

    Core Animation?

     : 시각적 요소에 대해 그래픽 랜더링 및 구성을 통해 애니메이션을 만드는 프레임워크

     : 시작 및 끝 포인트의 매개변수를 구성하고 애니메이션을 구현하면 Task가 자동으로 일을 수행함!

     : 드로잉 작업을 그래픽 하드웨어로 전달하여 레이어 객체가 조작할 수 있도록 렌더링 작업을 가속화해

       앱 속도 및 품질의 다운없이 높은 프레임과 자연스러운 애니메이션을 보여줍니다👏

     -> UIKit와 AppKit와 밀접한 관계!!

     : 드로잉 시스템 자체가 아닌 앱의 콘텐츠를 Layer를 가지고 관리한다는 점에서 코어 그래픽스와의 차이🌟

     : 코어 애니메이션은 뷰가 아닌 레이어를 다룬다

    Layer?

     : CALayer 객체로 컨텐츠 관리 및 조작 (비트맵으로 컨텐츠 캡쳐)

     : 뷰와의 차이는 자체 형태를 정의하지 않음 (비트맵으로 구성된 상태정보만 관리)

     -> 레이어가 앱에서 실제 드로잉 작업을 하진 않음 (컨텐츠 캡쳐 후 비트맵으로 캐싱 // backing store)

     -> 변경사항을 가진 애니메이션 트리거시 레이어의 비트맵/상태정보 -> 그래픽 하드웨어 전달

     -> UIView에 최소 1개씩 있고 렌더링 담당 (자신을 그려줄 Layer)

     -> 3D 구성된 2D (Layer Object)

     -> Layer는 두가지 유형의 좌표계를 사용하여 애니메이션을 만듬

      1) 점 기반 좌표계

      2) 단위 기반 좌표계

    Layer Tree의 종류

     : 코어 애니메이션은 CALayer의 프로퍼티를 직접 건드리지않고 아래와 같은 3개의 Layer Tree를 가지고 관리

     1) Model: CALayer: 해당 Layer의 실제 상태값

     2) Presentation: 애니메이션중에만 관리하며 뷰에 표시되는 현재 상태값을 반영

     3) Render: 실제 애니메이션을 수행하는 코어 애니메이션 전용

    Core Animation의 프로퍼티?

     : 다양한 프로퍼티들이 있어 아래 링크로 대체..!🤓
    ➡️https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/AnimatableProperties/AnimatableProperties.html#//apple_ref/doc/uid/TP40004514-CH11-SW1

     

    Animatable Properties

    Animatable Properties Many of the properties in CALayer and CIFilter can be animated. This appendix lists those properties, along with the animation used by default. CALayer Animatable PropertiesTable B-1 lists the properties of the CALayer class that you

    developer.apple.com

    Core Animation 만들어보기✍️

     1) 직선 움직이는 이미지

    import UIKit
    
    class ViewController: UIViewController {
        private struct KeyPath {
            struct Position {
                static let ps = "position"
                static let x = "position.x"
            }
        }
        
        private var square: CALayer = CALayer()
        let image = UIImage(named: "green.jpg")
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            configureSquare()
            configureButton()
        }
        
        func configureSquare() {
            square.frame = CGRect(x: 50, y: 100, width: 50, height: 50)
            square.contents = image?.cgImage
            view.layer.addSublayer(square)
        }
        
        func configureButton() {
            let animationButton = UIButton(frame: CGRect(x: 300, y: 100, width: 50, height: 50))
            animationButton.addTarget(self, action: #selector(moveAction), for: .touchUpInside)
            
            animationButton.setTitle("Move", for: .normal)
            animationButton.setTitleColor(.green, for: .normal)
            view.addSubview(animationButton)
        }
        
        @objc func moveAction() {
            let animation = CABasicAnimation()
            animation.keyPath = KeyPath.Position.x
            animation.fromValue = 50
            animation.toValue = 150
            animation.duration = 3
            animation.fillMode = CAMediaTimingFillMode.forwards
            animation.isRemovedOnCompletion = false
            
            self.square.add(animation, forKey: "basic")
            self.square.position = CGPoint(x: 150, y: 100)
        }
    }

     -> 이미지와 버튼을 구성

     -> 뷰 위에 레이어를 서브로 올려줌 (Square)

     -> 버튼을 생성하고 클릭 시 해당 애니메이션 동작

     -> self.square.position을 다시 잡아주는 구현이 없다면 애니메이션 동작 후 원래 자리로 돌아오게됨!!

       : 이유는 모델 레이어는 실제위치를 나타내주고 프레젠테이션 레이어는 애니메이션 되고 있는 궤적을 의미함으로

         현재 버튼에 궤적을 주었기에 애니메이션이 되지만 모델 레이어가 가진 실제 위치값은 변하지 않았음으로🧐

     -> KeyPath는 오타날 확률이 많아 구조체 상수로 별도 선언을 통해 관리

     -> fillMode와 isRemovedOnCompletion: 더 나은 성능 처리를 위한 프로퍼티

     

     [직선 움직이기 동작화면]

    2) 흔들리는 이미지

    @objc func shakeAction() {
        let animation = CAKeyframeAnimation()
        animation.keyPath = KeyPath.Position.x
        animation.values = [0, 20, -20, 20, 0]
        animation.keyTimes = [ NSNumber(value: 0), NSNumber(value: (1 / 6.0)),
                               NSNumber(value: (3 / 6.0)), NSNumber(value: (5 / 6.0)),
                               NSNumber(value: 1)]
        animation.duration = 1
        animation.isAdditive = true
            
        self.square.add(animation, forKey: "shake")
    }

     -> 쉐이크 기능을 위해 위 직선 움직이는 코드에서 selector만 shakeAction으로 변경해줌

     -> isAdditive: 현재 있는 좌표에서 상대적으로 애니메이션 동작하게 해줌 (절대적인 위치가 아닌 상대적 위치를 사용!!)


    [쉐이크 동작화면]

    3) 원을 그리며 도는 이미지

    @objc func rotateAction() {
        let rotateRect = CGRect(x: 0, y: 0, width: 100, height: 100)
            
        let animation = CAKeyframeAnimation()
        animation.keyPath = KeyPath.Position.ps
        animation.path = CGPath(ellipseIn: rotateRect, transform: nil)
        animation.duration = 5
        animation.isAdditive = true
        animation.repeatCount = 3
        animation.calculationMode = CAAnimationCalculationMode.paced
        animation.rotationMode = CAAnimationRotationMode.rotateAuto
            
        square.add(animation, forKey: "rotate")
    }

     -> rotationAuto가 없으면 자체적으로 회전을 하지 않음 (동그랗게 돌긴하지만 이미지는 돌지 않음)

     

    [로테이트 동작화면]

    [rotationAuto가 없는 동작화면]

     

     

    [느낀점]

    너무너무 어려운 코어애니메이션... iOS는 gif를 바로 넣을 수 없어 웹뷰를 통해 구현해줘야하는데..

    음.. 알곤 있고 쓸 수 있으면 베스트인..! 왜냐면 아무래도 코어 애니메이션으로 직접 구현을 해준다면 성능에서

    탁월하게 차이가 나기 때문에 꼭 알고 쓸줄 알아야겠다☺️

    일단 너무 범위도 광범위하고 개념만 훑고 가는 정도가 되었지만 키워드는 Layer에 대해 학습해보았고,

    CABasicAnimation / CAKeyframeAnimation 객체와 다양한 메서드로 다양하게 애니메이션이 지원된다🕴🏻

     

    [참고자료]

    야곰의 iOS-startcamp 중

    https://developer.apple.com/documentation/quartzcore

    https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004514

    https://velog.io/@delmasong/Core-Animation-Programming-Guide

    https://www.objc.io/issues/12-animations/animations-explained/

    'iOS' 카테고리의 다른 글

    CI / CD  (0) 2021.04.29
    Machine Learning  (0) 2021.04.20
    Homebrew & Vapor Toolbox  (0) 2021.03.30
    Core Graphics  (0) 2021.03.29
    Localization  (0) 2021.03.25
Designed by Tistory.