TIL(Today I Learned)

3월 4일(목)

학습내용

  • Animation
    • 애니메이션은 UIView의 프로퍼티 값을 바꿈으로써 만들 수 있다.
      • frame, bounds, center, transform, alpha, backgroundColor을 바꾸는 애니메이션을 만들 수 있다.
      • bounds는 자신만의 좌표 시스템을 갖는 사각형
      • frame은 부모의 좌표 시스템을 따르는 사각형
    • UIView.animate(withDuration:animations:)을 이용하여 애니메이션을 만들 수 있다.
      • UIView.animate은 비동기적으로 작동한다.
    • UIVIew.animateKeyframes(withDuration:delay:options:animations:completion:)와 UIView.addKeyframe(WithRelativeStartTime:relativeDuration:animations:)을 이용하면 여러 애니메이션을 동기적으로 작동하게 할 수 있다.
      • WithRelativeStartTime와 relativeDuration은 상대적인 시간이다. 예를 들어 0은 시작지점이고, 1은 마지막지점이며 1/2은 중간지점이다.
    • UIViewPropertyAnimator을 이용하면 애니메이션 시작, 정지와 동적인으로 애니메이션을 수정하는 것 등을 할 수 있다.

문제점/고민한점

  1. 수업시간에 야곰이 라이브 코딩한 ‘redView.bounds.origin.x = 30’ 은 무슨 의미일까?
  2. let redView = UIView(frame: CGRect(x: 20, y: 20, width: 100, height: 100)); redView.bounds.size = CGSize(width: 50, height: 50);의 결과는 (45, 45)에서 시작하는 50x50 사각형이였는데 왜 좌표가 이렇게 나왔을까?
  3. 하나의 애니메이션이 끝나면 다음 애니메이션이 작동하도록 하기 위하여(동기적으로 애니메이션을 실행) OperationQueue를 사용해 보았으나 제대로 되지 않았다. OperationQueue.main의 maxConcurrentOperationCount를 1로 하고, addOperations(…, waitUntilFinished: true)을 했을 때 왜 애니메이션이 작동하지 않았을까?

해결방법

  1. bounds의 기준 x 좌표점을 30부터 시작하겠다는 의미이다. 결과는 (30,0)이 기준점이 된다. (원래는 (0,0)이다.)
  2. 원래는 x는 20부터 120까지, y도 20부터 120까지인 정사각형인데, bounds의 길이와 높이가 50으로 줄어서 20과 120의 중점인 70을 기준으로 25를 줄인 45를 시작점으로 하고, 70 기준으로 25를 늘려서 95를 끝점으로 하는 사각형이 만들어 지는 것이다. (bounds의 사이즈를 바꾼 것이므로 처음 만들어진 사각형 좌표를 기준으로 사이즈를 바꾸는게 아닐까 싶다.)
  3. addOperations(…, waitUntilFinished: true)이 문제였다. waitUntilFinished을 false로 하니깐 애니메이션이 작동하긴 했다. (하지만 애니메이션이 동기적으로 실행되지 않고 모두 비동기적으로(동시에) 실행되었다.) 애니메이션이 작동하지 않은 이유는 main.sync에서 데드락이 발생하는 것과 동일한 이유이지 않을까 싶었다. 메인스레드에서 operation을 실행한 동시에 operation이 끝날 때 까지 메인스레드가 대기해야하기 때문에 데드락이 발생하여 애니메이션이 작동하지 않을 것 같다.

참고

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

https://yagom.net/forums/topic/야곰닷넷-질문모음-6/