
아무것도 모를때는 아래 방법을 썼지만, 조금 더 공부를 해보니 이 방법들을 쓰면 절대 안된다ㅋㅋㅋ
여유가 될 때, CoreAnimation과 UIProperty animation에 대해서 정리해보겠다.
애니메이션은 미리 완성된 형태를 재생하는 방식이다. 이에 대해서 사용자와의 상호작용이 이루어지긴 하지만, 한 애니메이션에서 여러가지 변수에 따라서 많은 것을 바꾸려면 수 많은 레이어가 필요하게 되고, 이는 결국 cpu와 메모리에 큰 부담으로 이어진다.
최근 내가 만들고 있는 애니메이션은, 물결 위에 도형이 둥둥 떠있는데, 공이 떠있는 애니메이션이 재생되면서, 동시에 사용자가 특정 행동을 했을때 도형의 색깔이나 모양이 바뀌는 애니메이션이다.

이를 위해서는 일단 공이 튀기는 애니메이션이 재생되어야 하고 사용자의 특정 행동에 따라 애니메이션 속의 공의 색이나 모양이 변경되어야 한다.
이를 위해서 몇가지 방법을 고민했고, 가장 좋다고 생각되는 두가지 방법을 생각해 내었다.
1. 애니메이션을 쪼갠다.
내가 현재 구현하려는 목적에 가장 적합하다고 생각해서 선택한 방식이다.
저렇게 둥둥 떠있는 방식을 4개로 쪼갰다. 둥둥 떠있는 애니메이션이 하나의 애니메이션처럼 보일 수 있지만, 사실은 4개의 애니메이션이 이어붙여져 있는 것이다.
이렇게 한 후, 애니메이션이 끝날 때마다, 새로운 애니메이션을 만들어서 바로 재생하면 끊김없는 애니메이션 재생이 가능하다.
func replayAnimation(size: Double, range: Double) {
makeAnimation(size: size, range: range, tag: 1)
self.node = shapeNodes.group()
animation = animations.combine().onComplete {
self.makeAnimation(size: size, range: range, tag: 2)
self.node = self.shapeNodes.group()
self.animation = self.animations.combine().onComplete {
self.makeAnimation(size: size, range: range, tag: 3)
self.node = self.shapeNodes.group()
self.animation = self.animations.combine().onComplete {
self.makeAnimation(size: size, range: range, tag: 4)
self.node = self.shapeNodes.group()
self.animation = self.animations.combine().onComplete {
if self.animation.state() == AnimationState.paused {
self.replayAnimation(size: size, range: range)
}
}
self.animation.play()
}
self.animation.play()
}
self.animation.play()
}
self.animation.play()
}
이 방법의 장점은 레이어(뷰) 하나를 통해서 모든 변화를 다룰 수 있다는 것이다.
현재 애니메이션을 통해 구현해야 하는 색 변화는 100개이다. 유저가 1부터 100에 해당되는 수치를 드래그를 통해 선택하면 그 즉시 그 색을 도형에 반영해주어야 하기 때문이다.
만약에 이어서 말하게 될 레이어 중첩 방법을 사용하게 된다면 레이어 100개가 필요하게 될 것이고, 과도한 cpu 부하가 일어나고 메모리 사용을 과도하게 될 것이다.
하지만 이 방식은 치명적인 단점이 있다.
애니메이션이 즉시 바뀌는 것이 아니라 딜레이가 걸린다. 애니메이션을 4개 혹은 그 이상으로 쪼갠다고 해도, 바로 변경사항이 반영되지는 않는다. 현재 재생되는 애니메이션이 끝나고 그 다음에 올 애니메이션에 변경사항이 반영되는 것이기 때문이다.
현재 내가 쪼갠 애니메이션은 하나당 0.25초씩 재생된다. 즉 총 1초 짜리 애니메이션을 4개로 쪼갠 것이다.
그래서 사용자가 애니메이션이 시작할 때 쯤 값을 변경한다면, 최대 0.25초의 딜레이가 생기게 된다. 물론 평균적으로는 0.1초 정도 안에 애니메이션이 변경될 것이다.
그럼에도 이 방법을 사용한 이유는 100개의 색 변경에 대한 애니메이션을 모두 만들 수는 없었기 때문이다. 그리고 0.25초의 딜레이는 직접 사용해보니 다행히 사용자가 체감할 정도의 딜레이는 아니었다.
만약에 애니메이션을 8개로 쪼개면, 최대 0.125초 안에 변하게 하는게 가능하기도 하다. 하지만 0.25초도 충분해서 일단 이대로 간다.
2. 레이어를 중첩시킨다.
각각의 레이어들을 모두 준비해서 동시에 재생시킨 후, 사용하는 레이어만 제외하고 모두 투명하게 유지시킨다.
유저가 입력한 값이 바뀔 때마다 해당 레이어의 alpha 값을 올려서 사용자에게 보이게 하고, 나머지 레이어는 모두 투명하게 만드는 식으로 변경할 수 있다.
하지만 이 방법은 사용해야 할 레이어가 수가 적을 때 유용하다.
이 방식의 장점은 무엇보다 변경점을 바로 적용할 수 있다는 점에 있다. 필요한 레이어를 바로 꺼내서 사용하고 사용하지 않는 레이어는 투명하게 만들면 되기 때문이다.
이 방식의 단점은 앞서 말했듯이 레이어의 수가 많아지면, cpu와 메모리 사용량이 과해질 수 있다.
'iOS 개발 > UIKit' 카테고리의 다른 글
[Swift] 앱 안에서 메일 보내기 (0) | 2021.11.20 |
---|---|
[GestureRecognizer] Gesture 잘 사용하기 - 동시에 여러 gesture 사용하기, 주의점 (0) | 2021.11.17 |
[UICollectionView] View를 하나씩 넘기기, 여러개씩 넘기기 (0) | 2021.11.17 |
[UIImageView] image 색 변경하기 (0) | 2021.11.09 |
[UITableVIew] automaticDimension 이 되지 않을때 (0) | 2021.10.18 |
[UIView] view를 fade in, fade out 시키는 방법 (0) | 2021.09.21 |
[Swift] viewcontroller에서 앱이 background에서 foreground 변환 감지 (0) | 2021.09.20 |
[NavgiationController] 네비게이션바 투명하게 만들기 (0) | 2021.09.14 |