๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS

[Swift/CoreAnimation] CABasicAnimation ์ด๋ž€

by ํ‹ด๋”” 2022. 6. 2.
728x90
๋ฐ˜์‘ํ˜•

Henry & Co.  ๋‹˜์˜ ์‚ฌ์ง„, ์ถœ์ฒ˜:  Pexels

์ „์ฒด ์ฝ”๋“œ ๋งํฌ

๊ณ„์ธต ์†์„ฑ์— ๋Œ€ํ•œ basic, single-keyframe ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ œ๊ณตํ•˜๋Š” ๊ฐ์ฒด

 

๊ฐ์ฒด ์ƒ์„ฑ

let animation = CABasicAnimation(keyPath: "position.x")
  • initializer์„ ํ†ตํ•ด keyPath๋ฅผ ์ง€์ •ํ•ด์„œ ๊ฐ์ฒด ์ƒ์„ฑ
let animation = CABasicAnimation()
animation.keyPath = "position.x"
  • keyPath๋Š” ๋”ฐ๋กœ ์ง€์ • ๊ฐ€๋Šฅ

keyPath

var keyPath: String? { get set }
  • receiver๊ฐ€ ์• ๋‹ˆ๋ฉ”์ด์…˜ํ•˜๋Š” ํ‚ค ํŒจ์Šค๋ฅผ ์ง€์ • -> opacity, backgroundColor, position ๋“ฑ (์™œ ์ŠคํŠธ๋ง์œผ๋กœ ๋ฐ›๋„๋ก ํ–ˆ์„๊นŒ ... ใ… ใ… )
 

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

  • ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ€๋Šฅํ•œ ๊ฐ’์€ ์œ„ ๋งํฌ ์ฐธ์กฐ

 

Interpolation values

fromValue : receiver๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์‹ค์ œ ๊ฐ’

toValue : receiver๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” end๊ฐ’

byValue : receiver๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” perform relative interpolation (?)

 

Interpolation Values๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฒ•

fromValue, byValue, toValue ๋ชจ๋‘ ์˜ต์…”๋„ ๊ฐ’์ด๋ฉฐ ์ด ์ค‘ ๋‘ ๊ฐœ๋Š” ๋ฐ˜๋“œ์‹œ ๊ฐ’์„ ๊ฐ€์ ธ์•ผ ํ•จ

 

- fromValue, toValue: fromValue -> toValue

- fromValue, byValue: fromValue -> (fromValue + byValue)

- byValue, toValue: (toValue - byValue) -> toValue

- fromValue: fromValue -> property์˜ current presentation value

- toValue: target layer์˜ presentation layer์˜ KeyPath ํ˜„์žฌ ๊ฐ’ -> toValue

- byValue: target layer์˜ presentation layer keyPath์˜ ํ˜„์žฌ ๊ฐ’ + byValue ์œผ๋กœ

 

opacity

  • ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ€๋Šฅํ•œ ๊ฐ’
  • 0.0 ~ 1.0 ๊นŒ์ง€์˜ ๊ฐ’์„ ๊ฐ€์ง€๋ฉฐ default๋Š” 1.0
  • ์‰ฝ๊ฒŒ ๋งํ•ด ์•ŒํŒŒ๊ฐ’์ด์ง€๋งŒ keyPath์—๋Š” "opacity"
    func opacityAnimation() {
        let animation = CABasicAnimation()
        animation.keyPath = "opacity"
        animation.fromValue = 0
        animation.toValue = 1
        animation.duration = 1
        testView.layer.add(animation, forKey: "basic")
    }

ใ„ด 0 ~ 1 ๊นŒ์ง€ 1์ดˆ ๋™์•ˆ

 

backgroundColor

var backgroundColor: CGColor? { get set }
  • layer์˜ backgroundColor๋ฅผ ๋ณ€๊ฒฝ. animatable ๊ฐ’
  • CGColor์„ ๋„˜๊ฒจ์ฃผ์–ด์•ผ ์ •์ƒ ์ž‘๋™ํ•จ. fromValue, toValue ๋ชจ๋‘ ์ž˜ ๋ชป ์ž…๋ ฅํ•ด๋„ ์—๋Ÿฌ ํ•œ์ค„ ์•ˆ๋‚˜์˜ค๋‹ˆ ์ฃผ์˜!
    func backgroundColorAnimation() {
        let animation = CABasicAnimation()
        animation.keyPath = "backgroundColor"
        animation.fromValue = UIColor.blue.cgColor
        animation.toValue = UIColor.yellow.cgColor
        animation.duration = 5
        testView.layer.add(animation, forKey: "basic")
        testView.layer.backgroundColor = UIColor.yellow.cgColor
    }

ใ„ด receiver์˜ backgroundColor์„ fromValue ํŒŒ๋ž€์ƒ‰์—์„œ toValue ๋…ธ๋ž€์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ. ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋‹ค ๋๋‚œ ๋’ค ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•ด ์ฃผ์–ด์•ผ ๋งˆ์ง€๋ง‰ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐ’์—์„œ ๋๋‚œ ๊ฒƒ์ฒ˜๋Ÿผ ํ•  ์ˆ˜ ์žˆ์Œ

 

position

var position: CGPoint { get set }
  • position์€ anchorPoint ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋Š”๋ฐ ์ด๋•Œ anchorPoint๋Š” layer์˜ bound์˜ center ๊ฐ’ (x point๋ผ๊ณ  x ๊ฐ’ ๋„˜๊ฒจ ์ฃผ๋Š” ๊ฒƒ ์•„๋‹˜. ์ขŒํ‘œ๊ณ„๋ฅผ ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ)

  • ์ด๋™ํ•˜๊ณ ์ž ํ•˜๋Š” ์ขŒํ‘œ๊ฐ€ x, y๋ผ๋ฉด toValue์— ์ „๋‹ฌํ•ด์•ผ ํ•˜๋Š” ๊ฐ’์€ [x+(width/2), y+(height/2)] ๊ฐ€ ๋˜๋ฉฐ ์‰ฝ๊ฒŒ center ๊ฐ’์„ ์‚ฌ์šฉํ•ด์„œ ๋„˜๊ธฐ๋ฉด ๊ณ„์‚ฐํ•˜๊ธฐ ์‰ฌ์›€ (toValue, fromValue ๋ชจ๋‘ anchorPoint์ด๋ฏ€๋กœ ์ฃผ์˜)
    func positionAnimation() {
        let animation = CABasicAnimation()
        animation.keyPath = "position.x"
        animation.fromValue = testView.center.x
        animation.toValue = 300
        animation.duration = 3
        testView.layer.add(animation, forKey: nil)
        testView.layer.position = CGPoint(x: 300, y: testView.center.y)
    }
  • ์˜ˆ์‹œ ์ฝ”๋“œ๋Š” x point๋งŒ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ์ด๋ฉฐ, ์—…๋ฐ์ดํŠธ ์œ„ํ•ด์„œ ๋งˆ์ง€๋ง‰์— layer.position ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋จ
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = [0, 0]
animation.toValue = [100, 100]
  • ์ถœ์ฒ˜ : apple developer document 

scale

var transform: CATransform3D { get set }
  • scale ๊ฐ’์„ ๋ณ€๊ฒฝ. CATransform3D ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งˆ์ง€๋ง‰์— layer ์—…๋ฐ์ดํŠธ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ CATransform3DMakeScale ๋ฅผ ์‚ฌ์šฉ 
    func scaleAnimation() {
        let animation = CABasicAnimation()
        animation.keyPath = "transform.scale.x"
        animation.fromValue = 1
        animation.toValue = 2
        animation.duration = 3
        testView.layer.add(animation, forKey: nil)
        testView.layer.transform = CATransform3DMakeScale(2, 1.0, 1.0)
    }
  • x๋ฅผ 2๋ฐฐ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ. duration ๋™์•ˆ animation ์ผ์–ด๋‚˜๋ฉฐ ๋๋‚œ ํ›„ layer์„ ์—…๋ฐ์ดํŠธ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ CATransform3DMakeScale๋กœ ๊ฐ’ ๋ณ€๊ฒฝ ์ด๋•Œ ์ธ์ž๋Š” ์ˆœ์„œ๋Œ€๋กœ x, y, z

๐Ÿฆ‘ ์ด์ƒํ•œ ์ ์ด๋‚˜ ๋ฌธ์ œ์‹œ ๋Œ“๊ธ€ ๋ถ€ํƒ๋“œ๋ ค์š”!

์ฐธ๊ณ  ์‚ฌ์ดํŠธ ๋ฐ ๋„์„œ

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

https://github.com/jrasmusson/swift-arcade/blob/master/Animation/CoreAnimation/Intro/README.md

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€