티스토리 뷰

반응형


+ ) 아ㅣㄴㅋㅋㅋㅋㅋ아니 아니 무슨 아니...아니 구글 애드센스 이넘들 왜 본문 ㄷ중간에도 광고넣지????????? 이건 진짜 별론데 얼른 빼도록 할게요 ㅇㄴ이거 도대체 어떻게 빼는건지??????? 애드센스 고수님들 알려주세요


안녕하세요 :) Zedd입니다.

정말 오랜만이죠!!!!!

지금zzzzz쓰고있는 글이 몇갠지.......어느게 먼저 올라갈지 몰라서 오랜만이라는 말을 계속 하네요.

사실 바쁩니다 주중에는 현생을 사느라 바쁘고 

주말에는 주중에 못한 것들을 하느라 바빠요 ㅠ_ㅠ

못본 영화도 봐야하고 게임도 해야하고 피아노도 쳐야하고.....ㅎㅎ

암튼 이 글이 제일 먼저 올라가길 바라면서 글을 시작할게요.


사실 이 addKeyframe을 공부해야지 해야지 하다가 미룬케이스인데...이번에 프로젝트 하면서 이 addKeyframe를 써야겠다고 생각했어요.

일단 addKeyframe이 도대체 먼지;;;;;봅시다.




UIView.animateKeyframes, UIView.addKeyframe





자...


UIView.animate(withDuration: 0.5, animations: {

            //animation.

        })


위 코드는 디게 많이 보셨죠?

아..이거 애니메이션 끝나고 이 애니메이션 했음 좋겠어. 근데 그게 또 끝나고 어떤 애니메이션을 또 해야돼...

자..이걸 보통의 방법으로 짜면


UIView.animate(withDuration: 0.5, animations: {

            //code

        }, completion: { (_) in

            UIView.animate(withDuration: 0.5, animations: {

                //code

            }, completion: { (_) in

                UIView.animate(withDuration: 0.5, animations: {

                    //code

                }, completion: { (_) in

                    //code

                })

        })

})


이렇게 짤 수 있습니다. ㅋ.ㅋ....ㅋㅋ.ㅋ...ㅋ.

이러면 보는 사람도 코드를 짜는 사람도 화나게 하는 코드가 만들어집니다 


그래서 animateKeyframes를 써야겠다 생각하고 이렇게 글을 씁니다. 


자, 그럼 2가지 메소드를 알아야 하는데요, 제목에 있다 시피 animateKeyframes와 addKeyframe입니다. 

animateKeyframes를 먼저 알아보도록 해요.


  • animateKeyframes

animate메소드와 같이, animateKeyframes는 UIView의 타입 메소드입니다.

현재 View에서 key-frame기반 애니메이션을 설정하는데 사용할 수 있는 애니메이션 블록 객체를 만드는 역할을 해요. 

역시나 Apple은 정의가 어렵..


파라미터들을 살펴봅시다.


1. duration : 전체(overall) 애니메이션의 지속시간(초단위)입니다. 음수 또는 0을 지정하면 애니메이션 없이 즉시 변경됩니다.


2. delay : 애니메이션을 시작하기 전에 대기 할 시간(초)를 지정합니다.


3. options : 애니메이션을 어떻게 수행 할지 나타내는 option mask입니다. 유효한 상수 목록을 보려면 UIView.KeyframeAnimationOptions를 참고하세요.


4. animations : view에 커밋할 변경내용이 포함된 블록객체입니다. 일반적으로 이 블록 내부에서 addKeyframe(withRelativeStartTime:relativeDuration:animations:)메소드를 호출합니다. 이러한 변경사항을 전체 기간(duration)동안 애니메이션으로 적용하려면, view값을 직접(directly)변경 할 수도 있습니다. 이 블록은 파라미터를 취하지 않으며, 반환값을 갖지 않습니다. 이 파라미터에 nil을 사용하지 마세요.


5. completion : 애니메이션 시퀀스가 끝날 때 실행될 블록객체입니다. 이 블록은 반환값이 없으며, completion handler가 호출되기 전에 애니메이션이 끝났는지 여부를 나타내는 single boolean argument를 사용합니다. 애니메이션의 지속시간이 0이면 이 블록은 다음 run loop cycle의 시작에서 수행됩니다. 이 파라미터에 nil값을 사용 할 수 있습니다.(default value가 nil으로 지정되어있는게 보이시죠?)


이 메소드는 keyframe기반 애니메이션을 설정하는데 사용 할 수 있는 애니메이션 블록을 만듭니다. keyframe자체는 이 메소드를 사용하여 생성한 초기 애니메이션 블록의 일부가 아닙니다. (The keyframes themselves are not part of the initial animation block you create using this method) 애니메이션 블록에서 addKeyframe(withRelativeStartTime:relativeDuration:animations:)메소드를 한 번 이상 호출하여 keyframe시간 및 애니메이션 데이터를 추가해야합니다. keyframe을 추가하면, 애니메이션이 현재 값에서 첫번째 keyframe으로, 다음 keyframe으로 view를 animate합니다.


애니메이션 블록에 keyframe을 추가하지않으면 애니메이션이 표준 애니메이션블록처럼 시작부터 끝까지 진행됩니다. 즉, 지정된 duration동안 현재 view값에서 새 값으로 애니메이션이 적용됩니다. 


ㅁ....


그럼 한번 써볼까용


자. 보통 


UIView.animateKeyframes(withDuration: 4, delay: 0, animations: {

        // addKeyframe(withRelativeStartTime:relativeDuration:animations:)

})


이 animateKeyframes메소드 안에 addKeyframe메소드를 호출한다고 나와있죠? 

아 그럼 addKeyframe메소드를 먼저 보는게 좋은가?...

ㅇㅋㅇㅋ..그럼 addKeyframe를 먼저 보도록 합시다.

참고로 animateKeyframes에는 duration과 delay, animations는 필수로 넣어줘야 합니다.



  • addKeyframe
addKeyframe역시 UIView의 타입메소드입니다. keyframe 애니메이션의 단일 frame에 대한 타이밍 및 애니메이션 값을 지정하는 메소드에요.

파라미터들을 살펴봅시다.


1. frameStartTime : 지정된 애니메이션을 시작 시간입니다. 값을 0에서 1까지의 범위여야 하며, 여기서 0 전체 애니메이션의 시작을 나타내고 1 전체 애니메이션의 끝을 나타냅니다("전체(overall)"라는 말에 신경을 써주세요.) 예를들어, 애니메이션의 길이가 2초인 경우, 시작 시간을 0.5 시작하면 전체 애니메이션이 시작된 1초후에 애니메이션이 실행됩니다. 


..? 0.5초로 지정했는데......애니에미션의 길이가 2....근데 1초후에 시작..?

이렇게 생각하시는 분들이 계실지도...모르는데요.


이렇게 생각하면 편합니다. 제가 animateKeyframes에서 전체(overall) 애니메이션 기간(duration) 2초로 설정했어요. 그럼 이건 "전체" 애니메이션의 시간입니다. 근데 addKeyframe에서는 frameStartTime 받죠? 근데 이건 0~1사이 값이야. 0 시작이고 1 애니메이션 끝이야.

그럼 0.5 뭐겠어요 1 반이자나요? 근데 1 전체 애니메이션의 기간이니까 1, 2 반인 1초후에 시작한다는 뜻이죠. 

이해가시나요...??? 그니까 (내가 시작하고싶은시간) / (전체 애니메이션 길이) 라고 생각하시면 됩니다.


2. frameDuration : 지정된 값으로 애니메이션을 적용하는 걸리는 시간입니다. 값은 0~1범위에 있어야 하며 전체 애니메이션 길이를 기준으로 시간의 (amount of time) 양을 나타냅니다. 값을 0으로 지정하면 애니메이션 블록에서 설정한 모든 속성이 지정된 시작시간에 즉시 업데이트 됩니다. 0 아닌 값을 지정하면 해당 시간 동안 속성이 애니메이션으로 나타납니다. 예를들어, 전체 duration 2초인 애니메이션의 경우, duration 0.5 지정하면 애니메이션 지속 시간이 1초가 됩니다. 

말이 뭐냐면 frameStartTime 원리는 같아요. 애니메이션이 1초동안 지속되게 하고싶어! 근데 전체(overall) duration 5초야!! 그럼 1/5 지정하면 됩니다.


3. animations : 수행하려는 애니메이션이 포함 블록객체입니다. (animations에서) view 계층구조에서 view 애니메이션 가능한 속성을 프로그래밍 방식으로 변경합니다. 블록은 파라미터를취하지 않으며 반환값을 갖지 않습니다. 파라미터는 nil 아니어야 합니다.


참고로 메소드가 animateKeyframes 애니메이션 블록 내에서 보통 호출된다고 그랬죠? addKeyframe 여러번 호출 수도 있어요!


..일단 그럼 예제코드를 봐봅시다.

일단 쉬운거 먼저해요



UIView.animateKeyframes(withDuration: 4, delay: 0, animations: {

        // addKeyframe(withRelativeStartTime:relativeDuration:animations:)

})


자 animateKeyframes의 animations 블록내에 보통 addKeyframe메소드를 추가한다고 그랬죠?

근데 animateKeyframes마지막 부분에 

"애니메이션 블록에 keyframe을 추가하지않으면 애니메이션이 표준 애니메이션블록처럼 시작부터 끝까지 진행됩니다. 즉, 지정된 duration동안 현재 view값에서 새 값으로 애니메이션이 적용됩니다."

라고 했는데요.

이거먼저 볼게요. 


애니메이션 블록에 keyframe을 추가 하지 않았을 때!



UIView.animateKeyframes(withDuration: 4, delay: 0, animations: {

            self.textView.alpha = 1

        })


이렇게 keyframe을 추가하지않고 그냥 이렇게..음..이렇게 view의 속성을 바꿔주는 코드를 넣어줬어요. 그러면 "표준 애니메이션 블록처럼 시작부터 끝까지 진행됩니다"라고 그랬죠? 



ㅇㅇㅇㅇ 진짜 그러네용 

쉽게 말하면


UIView.animateKeyframes(withDuration: 4, delay: 0, animations: {

            self.textView.alpha = 1

        })



이 코드가



UIView.animate(withDuration: 4, animations: {

            self.textView.alpha = 1

        })



이거랑 똑같은 결과를 가져다 준다~~~라는 것이죠.


그럼 다음! 이제 진짜 addKeyframe을 사용해봅시다.




UIView.animateKeyframes(withDuration: 3, delay: 0, animations: {

            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0/3.0, animations: {

                self.textView.alpha = 1

            })

            UIView.addKeyframe(withRelativeStartTime: 1/3, relativeDuration: 1.0/3.0, animations: {

                self.textView.alpha = 0

            })

            UIView.addKeyframe(withRelativeStartTime: 2/3, relativeDuration: 1.0/3.0, animations: {

                self.textView.alpha = 1

            })

        })



자....음....그냥..간단하게 만들어봤는데요. 그러니까 일단 한번 봅시다.

첫번째 addKeyframe.



UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0/3.0, animations: {

                self.textView.alpha = 1

            })


frameStartTime은 0에서 1사이의 값을 가진다고 위에서 그랬죠? 0은 시작시간이고 1은 애니메이션이 끝나는 시간이었어요.

전체 duration이 3이고 나는 처음에 "시작" 애니메이션을 위 애니메이션으로 하겠다!! 라는 거에요.

근데 해당 애니메이션의 적용되는 시간을 1초로 주는 것이죠. 역시나 0~1사이의 값이었음.

첫번째 애니메이션이 끝나면


UIView.addKeyframe(withRelativeStartTime: 1/3, relativeDuration: 1.0/3.0, animations: {

                self.textView.alpha = 0

            })



자, 두번째 keyframe으로 넘어오게 됩니다. 시작시간이 1/3이라는 건??? 전체 시간중에서 1초부터 시작하겠다~~라는 것입니다. 전체시간이 3초죠? 


아무튼 다 이런식입니다. 



UIView.animate(withDuration: 0.5, animations: {

            //code

        }, completion: { (_) in

            UIView.animate(withDuration: 0.5, animations: {

                //code

            }, completion: { (_) in

                UIView.animate(withDuration: 0.5, animations: {

                    //code

                }, completion: { (_) in

                    //code

                })

        })

})


즉?? 이런 completion 지옥을 탈출 할 수 있는것입니다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

그럼 보기에도 좋고...음..1.0/3.0이런거 보면 잘 이해가 안 갈 수도 있는데 그래도 completion지옥보단 낫지 않을까요? 

keyframe쓰면 오우 좀 개발 아는 놈인가 할지도 모름 하핫


그럼 저는 제 애니메이션들 keyframe으로 바꾸러 갈게요.

결국 이 글이 제일 먼저 올라가게 되네요!!!!!

XD



+ ) 적용 후기 

음......제가 예제를 엄청 쉬운거를 들었네요. 실제 쓸때는 


UIView.animate(withDuration: 0.25, animations: {

            //code

        }, completion: { (_) in

            UIView.animate(withDuration: 0.1, animations: {

                //code

            }, completion: { (_) in

                UIView.animate(withDuration: 0.5, animations: {

                    //code

                }, completion: { (_) in

                    //code

                })

        })

})



이런식으로 duration이 각각 다 다를 수 있는데..이걸 막 계산하려니 힘드네요. 만약 내가 animateKeyframes, addKeyframe를 모르는 상태로 이 코드를 봤다면..조금..그래서 이 애니메이션이 몇초 지속되는거지? 라는게 한눈에 안들어올것 같아요. 이걸 계산해야하니까 zzz...

completion 지옥 animation은 그래도 이해는 바로바로 되잖아요? 읽기가 힘들뿐이지...

급 고민이 되네




반응형