[문제] VC에 접근 방법에 따라 애니메이션이 적용되지않아보임

임혜정·2024년 9월 30일
0

스택뷰안에 몰아넣고
그래프막대를 하나의 뷰로 만든다음 계속 재사용하는 방식
애니메이션이 안되길래 mainAsync > 애니메이션은 되지만 막대그래프를 기준으로 잡은 레이블들 때문에 레이아웃이 랜덤해짐 ㅋㅋ

생각해보니 반복되는 요소들인데 뭐하러 하나하나 잡았지?
컬렉션뷰로 다시 만든다..

수정전

func setProgress(_ progress: CGFloat) {
        layoutIfNeeded()
        let targetProgress = min(max(progress, 0), 1)
        UIView.animate(withDuration: 0.9, delay: 0.5, options: [.curveEaseInOut], animations: {
            self.progressWidthConstraint?.update(offset: self.bounds.width * targetProgress)
            self.layoutIfNeeded()
        }, completion: nil)
    }
    

수정 후

func setProgress(_ progress: CGFloat) {
        DispatchQueue.main.async {
            self.layoutIfNeeded()
            let targetProgress = min(max(progress, 0), 1)
            UIView.animate(withDuration: 0.9, delay: 0, options: [.curveEaseInOut], animations: {
                self.progressWidthConstraint?.update(offset: self.bounds.width * targetProgress)
                self.layoutIfNeeded()
            }, completion: nil)
        }
    }

이 문제는 레이아웃 타이밍과 관련이 있었다. setProgress 메서드가 호출될 때 뷰의 레이아웃이 완전히 설정되지 않은 상태였을 가능성이 높다. DispatchQueue.main.async를 사용하여 메인 스레드의 다음 런 루프까지 실행을 지연시킴으로써, 우리는 레이아웃 사이클이 완료된 후에 애니메이션을 시작할 수 있게 되었다. 이는 Auto Layout이 뷰의 크기와 위치를 계산하고 적용할 충분한 시간을 가질 수 있게 해준다. 또한, 애니메이션 지연을 0으로 설정하여 화면 전환 직후 즉시 애니메이션이 시작되도록 했다. 결과적으로, 뷰의 초기 레이아웃이 완전히 설정된 상태에서 애니메이션이 시작되어 의도한 대로 부드럽게 동작하게 된다.

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️

0개의 댓글