[ToTheMoon] 트러블슈팅: 왼쪽 상단에서 확장되는 애니메이션 발생

황석범·2025년 2월 3일
0

내일배움캠프_iOS_5기

목록 보기
72/76
post-thumbnail

1. 문제 상황

인기 화폐 페이지로 이동할 때 왼쪽 상단에서 확장되는 애니메이션이 보인다

현재 화면의 구조

FavoritesContainerViewController (UIViewController)
│
├── topFavoritesView (TopFavoritesView)
│   ├── tabCollectionView (탭 버튼 2개: "인기 화폐", "관심 목록")
│   ├── underlineView (현재 선택된 탭 강조)
│   ├── searchButton (검색 버튼)
│   └── contentView (각 뷰 컨트롤러를 표시할 영역)
│
├── popularCurrencyVC (PopularCurrencyViewController)
│   └── 인기 화폐 리스트 뷰
│
└── favoriteListVC (FavoriteListViewController)
    └── 관심 목록 리스트 뷰
    

이런 구조로 FavoritesContainerViewController에서 contentView 영역에 각 탭에 맞는 뷰컨트롤러를 띄우고 그 뷰컨트롤러가 상황에 맞는 뷰를 띄우는 형식이다.

private func switchToViewController(for segment: SegmentType) {
    if segment == .popularCurrency {
        remove(child: favoriteListVC)
        add(child: popularCurrencyVC)
    } else {
        remove(child: popularCurrencyVC)
        add(child: favoriteListVC)
    }
}
 private func add(child viewController: UIViewController) {
     addChild(viewController)
     topFavoritesView.contentView.addSubview(viewController.view)
        
     viewController.view.snp.makeConstraints { make in
         make.edges.equalToSuperview()
     }

     viewController.didMove(toParent: self)
 }

2. 원인 분석

1. 뷰 컨트롤러의 기본 크기 문제

  • viewController.view를 topFavoritesView.contentView에 추가하기 전에, 해당 뷰의 초기 프레임이 .zero로 설정되어 있을 가능성
  • addSubview(viewController.view)를 호출하면, 초기 크기가 (0,0)이므로 첫 순간에 크기가 없었다가 make.edges.equalToSuperview() 제약 조건이 적용되면서 애니메이션이 발생

2. Auto Layout 적용 시점 문제

  • SnapKit을 사용하여 make.edges.equalToSuperview()로 오토레이아웃을 설정했지만, 이 과정에서 뷰가 처음에는 (0,0) 크기를 가졌다가 오토레이아웃이 반영되며 확장되는 애니메이션이 발생
  • addSubview 호출 직후에는 아직 레이아웃이 확정되지 않았고, layoutSubviews가 실행되면서 크기가 변경되며 애니메이션이 발생

3. 애니메이션 적용 여부

  • UIView의 기본적인 애니메이션 특성으로 인해 뷰의 크기가 갑자기 설정되면서 애니메이션이 적용
  • 특히, UIView.animate(withDuration:) 등의 애니메이션 코드가 명시적으로 없어도, 뷰의 크기 변화가 있는 경우 기본적으로 애니메이션이 발생

3. 해결 과정

1. 뷰를 추가하기 전에 크기를 미리 설정

viewController.view.frame = topFavoritesView.contentView.bounds
topFavoritesView.contentView.addSubview(viewController.view)

viewController.view.snp.makeConstraints { make in
    make.edges.equalToSuperview()
}

addChild(viewController)
viewController.didMove(toParent: self)

해결 안됨 equalToSuperview()로 제약 조건 잡는 과정에서 애니메이션 생기는것 같음

2. 레이아웃 강제 업데이트

뷰 추가 후 바로 layoutIfNeeded()을 호출하여 Auto layout을 즉시 완료 시키기

topFavoritesView.contentView.addSubview(viewController.view)

viewController.view.snp.makeConstraints { make in
    make.edges.equalToSuperview()
}

topFavoritesView.contentView.layoutIfNeeded()  // 즉시 레이아웃 적용

addChild(viewController)
viewController.didMove(toParent: self)

인기 화폐 페이지로 넘어갈 때는 애니메이션이 사라짐, 커스텀 인디케이터 화면에서 제약 조건 잡는 화면에서도 같은 현상 보임

3. 애니메이션 비활성화

만약 UIView.performWithoutAnimation {}을 사용하면, 레이아웃 변경 시 애니메이션이 발생하지 않도록 할 수 있습니다.

UIView.performWithoutAnimation {
    topFavoritesView.contentView.addSubview(viewController.view)

    viewController.view.snp.makeConstraints { make in
        make.edges.equalToSuperview()
    }

    topFavoritesView.contentView.layoutIfNeeded()
}

addChild(viewController)
viewController.didMove(toParent: self)

해결 안됨, UIView.perfrmWithoutAnimation{}은 애니메이션이 적용되는 뷰 변경 사항을 막기 위한 코드, addSubview()는 기본적으로 애니메이션이 발생하지 않음


결과

여기가 문제 원인이 아닌거 같다

profile
iOS 공부중...

0개의 댓글

관련 채용 정보