본문 바로가기

iOS

iOS 사용성 최대로 올려보자! (Part3) - UIView Interactive Animation

저번 포스팅에서는 ShapeShifter 를 다루는 방법을 살펴보았습니다.

 

이 포스팅은 "사용성 최대로 올려보자!"의 Series  중 일부입니다.

 

1.  iOS 사용성 최대로 올려보자! (Part1) - PaintCode

2. iOS 사용성 최대로 올려보자! (Part2) - ShapeShifter

3. iOS 사용성 최대로 올려보자! (Part3) - UIView Interactive Animation

4. iOS 사용성 최대로 올려보자! (Part4) - UIViewController Non Interactive Transition

5. iOS 사용성 최대로 올려보자! (Part5) - Easing function

6. iOS 사용성 최대로 올려보자! (Final) - UIViewController Interactive Transition

 

View는 두 가지의 Animation 형태로 분류됩니다.

1. Non Interactive Animation 

2. Interactive Animation 

 

확실히 이해를 돕기 위하여 데모를 먼저 살펴보죠!

 

 

Non Interactive Animation 

Non Interactive Animation는 정말 간단합니다. 

UIView.animate(withDuration: 1, animations: {
            self.nonInteractive.transform = CGAffineTransform(translationX: self.view.frame.maxX - 200, y: 0)
        })

평소에 자주 쓰시던 UIView.animate 를 사용하면 끝납니다.

 

Interactive Animation 

Interactive Animation 는 사용자 이벤트를 추적하면서 Animation 이 동작합니다.

 

UIViewPropertyAnimator: 뷰 변경 사항에 애니메이션을 적용하고 해당 애니메이션을 동적으로 수정할 수있는 클래스입니다.

https://developer.apple.com/documentation/uikit/uiviewpropertyanimator

 

UIViewPropertyAnimator - UIKit | Apple Developer Documentation

Class UIViewPropertyAnimator A class that animates changes to views and allows the dynamic modification of those animations. Declarationclass UIViewPropertyAnimator : NSObject OverviewA UIViewPropertyAnimator object lets you animate changes to views and dy

developer.apple.com

 

Animation의 상태

https://medium.com/@daniel_larsson/interactive-animations-with-uiviewpropertyanimator-284580951c62

 

Inactive: 

초기 상태입니다. 애니메이션이 완료되면 다시 돌아 오는 상태가 됩니다.

 

Active:

startAnimation, pauseAnimation을 호출하자마자 애니메이터가 활성화됩니다.

애니메이션이 자연스럽게 끝나거나 stopAnimation 메서드가 호출 될 때까지이 상태를 유지합니다.

 

Stopped: 

애니메이터는 stopAnimation을 호출하면 이 상태로 들어갑니다.

애니메이터는 재구성 및 Inactive 없이 먼저 Active 상태로 돌아올 수 없습니다.

 

 

 

이번 예제에서는 UIPanGestureRecognizer 와 함께 결합하여 사용하고 있습니다.

...더보기

UIPanGestureRecognizer는 드래깅 제스처를 구현한 UIGestureRecognizer의 구체적인 하위 클래스입니다.

 

일반적으로 제스처가 시작되면 상태를 .began로 설정하고 .changed로 업데이트를 보내고 .ended로 마무리합니다.

 

https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_uikit_gestures/handling_pan_gestures

 

구체적으로 순서를 설명하도록 하겠습니다.

 

 

이제 코드를 살펴보죠!

https://github.com/kimtaesu/InterativeAnimation/blob/master/InterativeAnimation/ViewController.swift

 

kimtaesu/InterativeAnimation

Contribute to kimtaesu/InterativeAnimation development by creating an account on GitHub.

github.com

 

@objc func pan(_ g: UIPanGestureRecognizer)

began

1. Animation이 실행 중이라면 실행 중인 Animation 을 삭제합니다.

 

2. 새로운 Animation을 추가합니다.

위에 예제에서는 왼쪽 > 오른쪽, 왼쪽 < 오른쪽으로 이동될 수 있도록 설정합니다.

 

3. Animation 이 완료되면 Position 상태를 업데이트합니다.

addCompletion 의 UIViewAnimatingPosition Argument는 start, end, current 상태 정보를 가지고 있습니다.

 

...더보기

UIViewAnimatingPosition

start: isReverse가 false (기본값)로 설정되어 있을 때 Animation 이 시작 위치

end: Animation의 최종 도착 위치

current: 현재 위치

 

4. pauseAnimation 를 호출하면 Active 이동하고 애니메이션이 즉시 일시 중지 된 상태가 됩니다.

 

changed

1. translation 를 통해 변환된 값을 구합니다.

Coordinate System 에서의 변환 (translate) 값입니다.

 

Zedd 님 블로그에 친절히 설명되어 있습니다.

 

https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html

 

2. view.frame.width 에서 (변환 값).x 를 나누어 진행률을 구합니다. 

3. fractionComplete (0.0 ~ 1.0) Animation의 진행률을 Update 합니다.

 

ended

1. pauseAnimation (Active 이동하고 애니메이션이 즉시 일시 중지 된 상태) 로 유지합니다.

2. 만약 진행률이 0.5 (절반) 보다 작다면 원래 상태로 돌리기 위해 isReversed = true 속성을 설정합니다.

3. continueAnimation 부분적으로 완전한 애니메이션의 타이밍과 지속 시간을 수정합니다.

continueAnimation 을 호출하면 완료될 Animation 이 실행됩니다. 

 

cancelled

1. cancelled 되었다면 Animation을 종료합니다.

 

마무리

이제 사용성이 좋은 앱을 만들기 위해 세 발자국 걸었습니다.

 

앞으로 Serise를 다 읽으시고 경험하신다면 좋은 앱 개발자가 될 것입니다.

 

SourceCode

 

소중한 시간 내어서 읽어주셔서 감사합니다