관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 18. setNeedsLayout, layoutIfNeeded (run loop, update cycle개념) 본문

iOS 기본 (swift)

[iOS - swift] 18. setNeedsLayout, layoutIfNeeded (run loop, update cycle개념)

jake-kim 2020. 9. 19. 20:07

1. Main Run Loop과 Update Cycle

앱 실행시,  iOS의 UIApplication이 메인 스레드에서  main run loop를 실행

- main run loop: 각종 이벤트들을 관찰하며, 그 이벤트들을 처리, 각 이벤트들에 맞는 핸들러를 찾아서 그들에게 권한을 위임 (버튼 클릭, 가로 모드전환, 위치 변화)

- update cycle: 이벤트 핸들러들이 처리하여 계산한 값을 토대로 UI가 실제적으로 반영되는 시점

 

2. setNeedsLayout과 layoutIfNeeded

- 둘 다 UIView 의 메소드

- 둘 다 최종적으로 layoutSubViews()메소드를 호출하는 예약 메소드

 

1) layoutSubViews()

- View의 레아아웃을 호출한 즉시 변경해주는 메소드 (단, view의 하위 뷰들도 모두 layoutSubViews()를 호출)

- update cycle에서 호출되는 메소드

- 직접 호출 하기에는 비용이 비싸므로, 직접호출은 지양

 

2) setNeedsLayout

- 비동기적

- 호출한 뷰와 하위 뷰들의 레이아웃을 업데이트하고 UI에 반여하고 싶을 때, 예약어 (스케줄링에 반영)

@IBOutlet var constraintButtonBottom: NSLayoutConstraint!

@IBAction func updateButtonHeight(_ sender: UIButton) {
    view.layoutIfNeeded()

    if self.viewHeight.constant == 3 {
        self.viewHeight.constant = 5
    } else {
        self.viewHeight.constant = 3
    }

    UIView.animate(withDuration: 2.0, animations: {
        self.view.setNeedsLayout() // 비동기
    })
}

* 위에서 에니메이션이 안보임: setNeedsLayout은 비동기이므로 updateButtonHeight(sende_:)함수가 종료되고 실행되므로

* view.layuoutIfNeeded()를 사용하는 이유: 기존에 기다리고 있던 뷰 업데이트들을 반영시키기 위함

 

3) layoutIfNeeded

- 동기적

- UI를 즉시 반영하고자 할 경우 사용 (위 코드에서 setNeedsLayout()을 layoutIfNeeded()로 할 경우, updateButtonHeight가 먼저 종료되지 않음)

Comments