화면전환 애니메이션 커스텀

1 답변 글타래를 보이고 있습니다
  • 글쓴이
    • 남수
      참가자
      • 글작성 : 13
      • 답글작성 : 2

      최근에 애니메이션에 관심이 많아지면서

      Q&A에도 질문을 해서 조언을 얻고 공부를 해봤습니다!!

       

      먼저 구현할 애니메이션을 설명 할게요!!

      앱스토어같이 누르면 살짝 튀어나오고 펼쳐지는 애니메이션을 구현해볼거에요

      예시

       

      UIViewControllerAnimatedTransitioning – Protocol

      UIPercentDrivenInteractiveTransition – Class

      UIViewControllerTransitioningDelegate – Protocol

      이 3개를 꼭 구현해서 이용해야해요

       

      애니메이션을 정의할 클래스를 만들어주고

      class AnimationTransition: UIPercentDrivenInteractiveTransition, UIViewControllerAnimatedTransitioning {
      
      // 애니메이션 동작시간
      
      func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { }
      
      // 애니메이션 효과정의
      
      func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { }
      
      }
      
      

      이 객체를 Delegate에 적용시켜주면 애니메이션을 원하는대로 구현 해볼수있어요

      delegate에는

      // present시 실행될 애니메이션
      
      animationController(forPresented presented...)
      
      // dismiss시 실행될 애니메이션
      
      animationController(forDismissed dismissed...)
      
      // present 진행중 실행될 애니메이션 ( ex: 중간에 드래그로 멈추고 끌면서 여는경우 )
      
      interactionControllerForPresentation
      
      interactionControllerForDismissal
      
      navigationControlle(..., from fromVC: UIViewController, to toVC: ...)
      
      

      UIViewControllerTransitioningDelegate에는 위에서부터 4개의 함수가 있고,

      UINavigationControllerDelegate 에는 1개의 함수가있어요

      다시돌아와서

      애니메이션을 만들어볼께요

      UIPercentDrivenInteractiveTransition, UIViewControllerAnimatedTransitioning를 상속,채택한 객체에

      func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
      
      let containerView = transitionContext.containerView
      // 다음 보여질뷰 참조
      guard let toView = transitionContext.view(forKey: .to) else { return } containerView.addSubview(toView)
      
      }
      
      

      transitionContext.containerView – 뷰를 담을 수 있는 전체 틀이라고 생각하면되요

      transitionContext.view를 통해서 보여지거나, 사라질 뷰를 가져올거에요

      키값에는 .from, .to 이 잇어요

      from – (~로부터) 앞으로 가려질뷰, 사라질 뷰를 가르켜요

      to – (~으로) 앞으로 보여질뷰, 나타날 뷰를 가르켜요

       

      저 같은경우는

      첫번째화면에서(From)

      두번째화면으로(To)

      Present할거고

      그 뷰에 애니메이션을 적용할거니까

      To를 참조해야겟죠?

       

      여기까지는 기본적으로 다음 뷰를 띄우는 코드였구요

      cell을 클릭하면 frame을 저장하고 그 위치부터 다음뷰가 시작될거에요

       

      func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
      
      let containerView = transitionContext.containerView
      
      // 다음 보여질뷰 참조
      
      guard let toView = transitionContext.view(forKey: .to) else { return }
      
      // 보여질뷰의 위치잡기 (Cell의 frame)
      
      toView.frame = originFrame!
      
      // MARK: CGAffineTransform을 이용한 효과
      
      toView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) containerView.addSubview(toView)
      
      // hierarchy on top
      
      containerView.bringSubviewToFront(toView)
      
      toView.layer.masksToBounds = true
      
      toView.layer.cornerRadius = 20
      
      toView.alpha = 0
      
      // MARK: 애니메이션 적용
      
      UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.5, options: .curveEaseOut, animations: {
      
      // MARK: 원래자리로 되돌리면서 애니메이션 이동효과
      
      toView.transform = .identity toView.alpha = 1
      }) { _ in
      toView.translatesAutoresizingMaskIntoConstraints = false
      toView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
      toView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
      toView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor).isActive = true
      toView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor).isActive = true
      UIView.animate(withDuration: 1) {
      
      containerView.layoutIfNeeded()
      
      }
      
      }
      
      transitionContext.completeTransition(true)
      
      }
      
      

      이 애니메이션 객체를 delegate에 return값으로 넣어주고

      다음화면의 속성에

      secondVC.transitioningDelegate = self
      
      secondVC.modalPresentationStyle = .custom
      

      이 두속성을 꼭 해주셔야 적용됩니다!!

      • 이 게시글은 남수에 의해 4 years, 7 months 전에 수정됐습니다.
      • 이 게시글은 남수에 의해 4 years, 7 months 전에 수정됐습니다.
      • 이 게시글은 남수에 의해 4 years, 7 months 전에 수정됐습니다.
      • 이 게시글은 남수에 의해 4 years, 7 months 전에 수정됐습니다.
    • 야곰
      키 마스터
      • 글작성 : 37
      • 답글작성 : 579

      크으 커스텀뷰 장인! 👏
      오늘은 리저브 부자네요 ㅎㅎ
      좋은 글 고맙습니다!

1 답변 글타래를 보이고 있습니다
  • 답변은 로그인 후 가능합니다.

logo landscape small

사업자번호 : 743-81-02195
통신판매업 신고번호 : 제 2022-충북청주-1278 호
고객센터 : 카카오톡채널 @yagom