본문 바로가기

iOS

[iOS] Core Animation (feat. Layer, CABasicAnimation)

# Core Animation

[정의]

시각적요소를 렌더링, 합성하고 애니메이션화합니다.

  • 즉, Core Animation은 iOS/ OS X 에서 사용할 수 있는 그래픽 렌더링 및 애니메이션 인프라이다.
    (Core Animation은 드로잉 시스템 그자체가 아니다. 하드웨어에서 앱의 컨텐츠를 합성/조작 하기위한 인프라임)
  • Core Animation인프라에는 핵심이 Layer(CALayer)가 존재한다.
    이는 컨텐츠를 관리/조작 하는데 사용됩니다(Layer는 그래픽 하드웨어로 쉽게 조작할 수 있도록 비트맵으로 컨텐츠를 캡쳐합니다.)
  • Core Animation을 사용하면 대부분의 작업이 자동으로 수행된다.
    그래서 시작과 끝지점과 같은 매개변수를 구성하고 CoreAnimation이 시작하도록 지시하면된다.
  • Core Animation은 실제 드로잉 작업을 렌더링 작업을 가속화하기위해 온보드 그래픽 하드웨어로 전달한다.
    앱의 속도를 저하시키지않고 높은 프레임속도와 부드러운 애니메이션을 만들수 있다

  • CALayer가 1번으로 공문에 나옴
  • 그룹화시켜서 animation을 관리하고 싶으면 animationgroup을 사용할 수 있음
  • animation을 관리하는 프로퍼티라고하면 CAPropertyAnimation이 제일 많이 사용한다.
  • Layer에있는 프로퍼티의 값들이있는데 그를 변경시키면 자동으로 애니메이션을 실행시켜준다.
  • CAAimationGroup
  • CABasicAnimation
  • CATransition

# 학습활동

  • Layer에 정의에대해서 확인했다.
  • anchorPoint는 rotatioon라는 중심점을 말한다.
  • Layer에는 두가지가 존재한다. (presentationLayer와 modelLayer가 존재한다.)
  • animation 후 뷰가 다시 원위치로 돌아오는 이유

model: 기본적으로 실제 가지는 layer의 값이다(예 - 색상, 위치, 등등)
presentationLayer: 움직이는, 동작하는 순간의 layer의 값이다.
두 가지의 방법이있다.
그래서 animation을 하고난 후에도 frame의 위치를 그대로 두고싶다면
첫번째방법 model과 presentationLayer 둘다 값을 바꿔줘야합니다. => 프로퍼티.layer.position = 값
두번째방법, fillMode = .forwards isRemovedOnCompletion = false

  • isAdditive의 원리에서 확인했다.

true일 경우 상대값으로 바꿔서 현재 view를 기준으로 animation을 적용해준다
그래서 x , y를 기준으로 원래는 애니메이션이 되는데 그렇지않고 현재 view에 위치에서 애니메이션이 되는것임

- 이 두가지 방법중에서 어느것이 좋을까 ??

전자를 권장하고있따 왜냐하면 나중에 Layer의 값을 수정하거나 변경하게될때 화면에 보여지는 값을 기준으로 생각할 수 있는데 실제의 값을 다르기떄문에 다르다

  • layer.setAffineTransform(rotationAngle: ) vs transform = CGAffineTransform(rotationAngle: )

# core Animation을 직접 사용해 그려보자

CABasicAnumation을 사용해보자 (위치, 투명도, 색상, 크기)

  • position(위치)
    let animation = CABasicAnimation(keyPath: "position.y")
    animation.fromValue = 850
    animation.toValue = 0
    animation.duration = 4

    imageView.layer.add(animation, forKey: "basic")
 

  • scale(크기)
    let animation = CABasicAnimation(keyPath: "transform.scale")
    animation.fromValue = [1, 1]
    animation.toValue = [5, 5]
    animation.duration = 4

    imageView.layer.position.x = CGFloat(positionx)
    imageView.layer.position.y = CGFloat(positiony)

    imageView.layer.add(animation, forKey: "basic")
 

  • opacity(투명도)
	    let animation = CABasicAnimation(keyPath: "opacity")
    animation.fromValue = 0
    animation.toValue = 1
    animation.duration = 4

    imageView.layer.add(animation, forKey: "basic")
 

  • backgroundColor(색상)
	    let animation = CABasicAnimation(keyPath: "backgroundColor")
    animation.fromValue = UIColor.red.cgColor
    animation.toValue = UIColor.systemYellow.cgColor
    animation.duration = 4

    imageView.layer.add(animation, forKey: "basic")
 

  • CAKeyframeAnimation, shake
	    let animation = CAKeyframeAnimation(keyPath: "position.x")
    animation.values = [0, 10, -10, 0]
//    let keytimesValue = [NSNumber(value: 0), NSNumber(value: 1/6), NSNumber(value: 3/6), NSNumber(value: 5/6), NSNumber(value: 1)]
//
//    animation.keyTimes = keytimesValue
    animation.duration = 0.3

    animation.isAdditive = true

    imageView.layer.add(animation, forKey: "shake")
	
 

  • rotation
    
	let boundingRect = CGRect(x: -90, y: -150, width: 150, height: 150)

    let orbit = CAKeyframeAnimation(keyPath: "position")
    orbit.path = CGPath(ellipseIn: boundingRect, transform: nil)
    orbit.duration = 4
    orbit.isAdditive = true
    orbit.repeatCount = HUGE
    orbit.calculationMode = .cubicPaced
    orbit.rotationMode = .rotateAutoReverse
    imageView.layer.add(orbit, forKey: "orbit")
 

# Reference