clamp
Clamp
clamp
글쓰기 관리
전체 방문자
오늘
어제
  • 분류 전체보기 (509)
    • IOS (85)
    • SwiftUI+TCA+Combine (9)
    • RxSwift + MVVM (56)
    • Clean Architecture (12)
    • SWIFT (56)
    • iOS - TDD (2)
    • 디자인패턴 (4)
    • CS (56)
      • 알고리즘 (29)
      • 운영체제 (15)
      • 자료구조 (2)
      • 네트워킹 (4)
      • 기타 (6)
    • 회고 (0)
    • Firebase (18)
    • SwiftUI (10)
    • iOS - UIKit (11)
    • iOS - 오픈소스 (6)
    • 코딩테스트 (166)
      • 프로그래머스 (164)
    • 정보처리기사 (14)
    • GitHub (2)
글쓰기 / 관리자

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • uikit
  • Q
  • Swift
  • ㅅ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
clamp

Clamp

[iOS] - Drawing Cycle(Layout Cycle)
IOS

[iOS] - Drawing Cycle(Layout Cycle)

2023. 3. 29. 16:16
iOS에서 메인 쓰레드는 1초에 60번 ~ 120번(기기의 Hz마다 다르다) 화면을 다시그린다.

무조건 60번, 120번을 다시 그리는 게아니라 필요한 경우! 화면을 다시그린다.

 

화면을 그리는 동안엔 아래와 같은 함수 호출 싸이클이 생긴다.

 

updateConstraints() ➡️ layoutSubviews() ➡️ draw()

 

updateConstraints (오토레이아웃이 업데이트 되야 할 때에만)

  • 제약: 오토레이아웃을 업데이트 한다.
  • 현재 기기의 화면 크기를 기준으로 제약을 업데이트한다.
  • 동적인 오토레이아웃 변경이 일어날 경우 제약조건을 변경한다.
  • 명시적으로 호출할 순 없다.
  • 오토레이아웃으로 인한 제약이 확정되는 시기이다.
// 테이블 뷰 셀 같은 컴포넌트 요소를 코드로 구성할 때 활용할 수 있다.

// updateConstraints에서 레이아웃 제약이 확정된다.
override func updateConstraints() {
        setConstraints() // 오토레이아웃을 설정하는 함수
        super.updateConstraints()
    }
    
    //반드시 super.updateConstraint()를 오토레이아웃 설정 후에 호출해야한다. 출처 - document

 

직접 호출이 아닌 updateConstraints를 호출할 수 있도록 예약하는 형태의 메서드가 존재한다.

setNeedsUpdateConstraints() / updateConstraintsIfNedded()

 

layoutSubviews()

  • (하위뷰의) 레이아웃: 위치 / 크기를 재조정한다.
  • frame 기준으로 알 수 있는 시점 / 하위 뷰들의 frame등 직접 설정이 가능한 시기
  • 뷰 들의 레이아웃 프레임이 정해지는 시기이다.
  • 호출하면 해당 View의 모든 subView들이 layoutSubviews()를 연달아 호출한다.
  • 소모되는 비용이 너무 크기 때문에 직접호출은 하지않는다.❌
// 테이블 뷰 셀 같은 컴포넌트 요소를 코드로 구성할 때 활용할 수 있다.
// 오토레이아웃(제약)으로 인해 뷰들의 frame(크기)가 정해지는 시점이기 때문에 정해진 크기로 인한 작업들을 할 수 있다.
    override func layoutSubviews() {
        super.layoutSubviews()
        self.mainImageView.clipsToBounds = true
        self.mainImageView.layer.cornerRadius = self.mainImageView.frame.width / 2
    }

그렇기 때문에 직접 호출이 아닌 layoutSubView를 호출할 수 있도록 예약하는 형태의 메서드가 존재한다.

setNeedsLayout() / layoutIfNedded()

 

 

draw

  • 실제로 화면을 다시 그리는 단계: 실제 내부의 컨텐츠를 다시 그린다.

 

이 3개의 함수가 호출되는데 자동으로 호출되는데, 1초에 화면을 60번 다시그린다면 이 3개의 함수의 호출이 1초에 60번마다 일어난다는 것이다.

 

하지만 애플은 updateConstraints, layoutSubviews, draw는 Update Cycle에서 수행되는게 더 바람직 하므로 직접 호출하지 말라고한다.

 

setNeedUpdateConstraints(), setNeedsLayout(), layoutIfNeeded(), setNeedsDisplay()

그래서 존재하는 것이 setNeedUpdateConstraints(), setNeedsLayout(), layoutIfNeeded(), setNeedsDisplay() 이다.

이 메서드들은 각각 아래와 같은 업데이트를 명시적으로 예약한다.

setNeedUpdateConstraints() => 제약

setNeedsLayout(), layoutIfNeeded() => Layout

setNeedsDisplay() => Display

 

이들이 호출되면 시스템은 이를 체크해두고 부른 메서드에 맞게 Update Cycle에서 updateConstraints, layoutSubviews, draw를 호출하게 된다.

 

이를 직접 호출하지 않아도

  • View의 크기 변경
  • SubView 추가
  • ScrollView에서 Scroll발생
  • 디바이스 회전으로 인한 화면 표시 모드 변경
  • View의 제약 변경

과 같은 상황에서는 자동으로 호출된다. 그래서 setNeedsLayout(), layoutIfNeeded(), setNeedsDisplay()를 직접 호출하지 않아도 UI가 업데이트된 것이다.

 

 

UpdateCycle을 기다리지 않아도 layoutIfNeeded(), setNeedsDisplay()를 호출하면 바로 View를 업데이트하게된다.

 

layoutIfNeeded()는 Constraints를 통해 애니메이션을 구성하고 싶을 때 유용하게 사용된다.

 단순 Constarint를 변경하는 애니메이션을 만들 경우 이에대한 처리는 Update Cycle에서 처리되기 때문에 애니메이션 효과를 줄 수 없다.

하지만 Constraint 변경 후 layoutIfNeeded()메서드를 애니메이션 코드에 추가하면 layoutIfNeeded() 가 순차적으로 처리되며 애니메이션을 확인할 수 있게된다.

 

 

 

 

저작자표시 비영리 동일조건 (새창열림)
    'IOS' 카테고리의 다른 글
    • [IOS] - UIWindow
    • [iOS] App Bundle: 앱 개발의 핵심 구성 요소
    • [iOS] - 파일시스템(Document, Library, tmp...)
    • [iOS] - 앱의 생명주기 App's Life Cycle (AppDelegate, SceneDelegate)
    clamp
    clamp
    주니어 iOS개발자의 발악!!!!!!!

    티스토리툴바