레이아웃 핵심 프로세스

2025. 4. 27. 15:17·iOS/UIKit
반응형

👋 들어가기 전

이전에 학습한 https://hamp.tistory.com/210  디바이스 회전 포스팅 마지막 질문인

회전 시 UICollectionView와 같은 cell에 대한 레이아웃 갱신을 이번 포스팅에서 이어가보자.

🏁 학습할 내용

  • 레이아웃의 core process
  • invalidateLayout

🚅 레이아웃 core process

먼저 전체적인 과정은 위와 같다.

각 과정을 차례대로 알아보자.

🚦prepare

⭐️ 정의

레이아웃 계산하기 전 미리 필요한 데이터나 상태를 준비하는 함수

간단히 말하면 레이아웃을 그리기 전 사전 작업(셀 위치 계산, 내부 캐시 초기화 등)을 준비

📞 호출 시기

CollectionView의 내용이 처음 보일 때 또는 layout이 invalidated 될 때 호출된다.

 

🖼️ collectionViewContentSize

⭐️ 정의

레이아웃에서 제공해주는 내용을 보여줄 Size를 알려준다.

 

🏛️ layoutAttributesForElements

⭐️ 정의

지정된 rect안에 있는 cell, header, footer등의 레이아웃 속성을 탐색

탐색이 끝나면 탐색 정보를 토대로 CollectionView가 화면을 그린다.


♻️ invalidateLayout()

⭐️ 정의

현재 적용된 layout 무효화 시키는 플래그 함수

여기서 주의할 점은 지금 당장 바꾸는게 아닌 다음 Run Loop에 적용

 

view의 update cycle에 플래그를 던지는 setNeedsLayout()과 비슷한 역할


⌨️ 실습

버튼을 통해 invalidateLayout 호출 시 Layout에서 어떤 함수들이 호출되는 지 살펴보자.

LoggingFlowLayout.swift

final class LoggingFlowLayout: UICollectionViewFlowLayout {

    override func invalidateLayout() {
        print("➡️ [invalidateLayout] called")
        super.invalidateLayout()
    }

    override func prepare() {
        print("🛠️ [prepare] called")
        super.prepare()
      
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        print("📐 [layoutAttributesForElements] called for rect: \(rect)")
        return super.layoutAttributesForElements(in: rect)
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        print("🎯 [layoutAttributesForItem] called for indexPath: \(indexPath)")
        return super.layoutAttributesForItem(at: indexPath)
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        print("🔄 [shouldInvalidateLayout] called with newBounds: \(newBounds)")
        return super.shouldInvalidateLayout(forBoundsChange: newBounds)
    }
}

최초 present

invalidateLayout()

 

정확히 prepare부터 다시 시도 되는 것을 확인할 수 있다.

 

다시말하면 invalidateLayout은 오직 Layout과 관련 업데이트를 특정 시점에 변경하고 싶을 때

사용할 수 있다.


⚠️ 주의할 점

reload 데이터를 적용했도 cell을 다시 그리기 때문에 Layout 변경을 하는 것 처럼보인다.

 

여기서 사용목적을 분명히 구분하고 사용해야한다.

reload데이터는 dataSource의 변경을 알림으로써 cell을 다시 그리는 것이고

 

invalidateLayout은 dataSource 변경과 상관 없이 Layout 변경의 필요성에 의해서 호출해야한다.

 

가장 단순한 예로는 보여지는 데이터가 같은데 디바이스가 회전함으로써 layout 변경이 필요될 때

호출하여 가로/세로의 UI를 다르게 표현할 수 있다


출처

http://developer.apple.com/library/archive/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html#//apple_ref/doc/uid/TP40012334-CH5-SW1

 

Creating Custom Layouts

Creating Custom Layouts Before you start building custom layouts, consider whether doing so is really necessary. The UICollectionViewFlowLayout class provides a significant amount of behavior that has already been optimized for efficiency and that can be a

developer.apple.com

https://developer.apple.com/documentation/uikit/uicollectionviewlayout/invalidatelayout()

 

invalidateLayout() | Apple Developer Documentation

Invalidates the current layout and triggers a layout update.

developer.apple.com

 

반응형

'iOS > UIKit' 카테고리의 다른 글

[Text 시리즈 2] Font Metrics 와 Glyph metrics  (5) 2025.07.18
HitTest와 touchesBegan은 무슨 관계가 있을까?  (0) 2025.05.30
디바이스 회전 대응  (0) 2025.04.26
Transitioning  (0) 2025.04.19
UIStackView 뿌시기  (0) 2025.01.29
'iOS/UIKit' 카테고리의 다른 글
  • [Text 시리즈 2] Font Metrics 와 Glyph metrics
  • HitTest와 touchesBegan은 무슨 관계가 있을까?
  • 디바이스 회전 대응
  • Transitioning
Hamp
Hamp
남들에게 보여주기 부끄러운 잡다한 글을 적어 나가는 자칭 기술 블로그입니다.
  • Hamp
    Hamp의 분리수거함
    Hamp
  • 전체
    오늘
    어제
    • 분류 전체보기 (340)
      • CS (30)
        • 객체지향 (2)
        • Network (7)
        • OS (6)
        • 자료구조 (1)
        • LiveStreaming (3)
        • 이미지 (1)
        • 잡다한 질문 정리 (0)
        • Hardware (2)
        • 이론 (6)
        • 컴퓨터 그래픽스 (0)
      • Firebase (3)
      • Programing Langauge (41)
        • swift (34)
        • python (6)
        • Kotlin (1)
      • iOS (135)
        • UIKit (37)
        • Combine (1)
        • SwiftUI (34)
        • Framework (7)
        • Swift Concurrency (22)
        • Tuist (6)
        • Setting (11)
        • Modularization (2)
        • Instruments (6)
      • PS (59)
        • 프로그래머스 (24)
        • 백준 (13)
        • LeetCode (19)
        • 알고리즘 (3)
      • Git (18)
        • 명령어 (4)
        • 이론 (2)
        • hooks (1)
        • config (2)
        • action (7)
      • Shell Script (2)
      • Linux (6)
        • 명령어 (5)
      • Spring (21)
        • 어노테이션 (6)
        • 튜토리얼 (14)
      • CI-CD (4)
      • Android (0)
        • Jetpack Compose (0)
      • AI (21)
        • 이론 (10)
        • MCP (1)
        • LangGraph (10)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    concurrency
    dp
    SwiftUI
    protocol
    GIT
    투포인터
    lifecycle
    dfs
    Swift
    프로그래머스
    boostcamp
    UIKit
    CS
    IOS
    property
    dispatch
    Spring
    Tuist
    백준
    AVFoundation
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
Hamp
레이아웃 핵심 프로세스
상단으로

티스토리툴바