본문 바로가기
IT/Swift 노트

awakeFromNib(), layoutSubviews(), preferredLayoutAttributesFitting()

by 33.0 2025. 4. 17.
728x90

collectionView의 셀을 구성하다 보니까 세개의 닮은 듯 다른 메서드를 발견하였다. 

비슷비슷해보이는데 과연 어떤 메서드인지 알아보자. 

 

awakeFromNib() 

nib 파일에서 깨어나다 라는 의미를 갖고 있다. (nib 파일은 interface builder에서 만든 사용자 인터페이스 요소들을 저장하는 파일)

호출 시점

UI요소가 메모리에 로드된 직후, 화면에 표시되기 직전에 호출되는 메서드 

사용하는 이유

스토리보드에서 설정할 수 없는 속성들을 코드로 설정할 때 사용 

공식문서 

https://developer.apple.com/documentation/objectivec/nsobject-swift.class/awakefromnib()

 

awakeFromNib() | Apple Developer Documentation

Prepares the receiver for service after it has been loaded from an Interface Builder archive, or nib file.

developer.apple.com

예제 코드 

override func awakeFromNib() {
    super.awakeFromNib()
    // 셀의 기본 모양 설정
    contentView.backgroundColor = .lightGray
    contentView.layer.cornerRadius = 8
}

 

 

layoutSubviews()

Subview는 하위 뷰를 뜻한다.

호출시점

뷰의 크기나 위치가 변경될 때마다 자동으로 호출 

사용하는 이유

하위 뷰들의 크기와 위치를 조정하는 데 사용 

공식문서 

https://developer.apple.com/documentation/uikit/uiview/layoutsubviews()

 

layoutSubviews() | Apple Developer Documentation

Lays out subviews.

developer.apple.com

 

예제 코드 

override func layoutSubviews() {
    super.layoutSubviews()
    // 이미지뷰와 텍스트 레이블 크기를 셀 크기에 맞게 조정
    imageView?.frame = contentView.bounds
    textLabel?.frame = contentView.bounds
}

 

공식문서를 보다보면 IOS18 이상에서는 하위뷰에 대해서 Automatic Trait Tracking을 지원한다고 나와있다.  

Automatic Trait Tracking은 시스템 환경이 변경될 때 반응 한다. 

즉 다크모드/ 라이트모드 대응, 화면방향 변경, 접근성 설정(글자크기) 변경 등에 대응하는 코드이다. 

 

여기에 대한 코드도 덧붙여서 적자면 

class FoodCell: UICollectionViewCell {
    
    // 기존 코드는 그대로 유지
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 고정된 크기 유지
        let size = CGSize(width: FoodViewController.cellSize, height: FoodViewController.cellSize)
        self.frame.size = size
        contentView.frame.size = size
        
        // 이미지뷰와 텍스트 레이블 크기 조정
        imageView?.frame = contentView.bounds
        textLabel?.frame = contentView.bounds
    }
    
    // 새로 추가: Trait 변경 감지 메서드
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        
        // 다크 모드/라이트 모드 변경 감지
        if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
            updateColorsForCurrentTheme()
        }
    }
    
    // 현재 테마에 맞게 색상 업데이트하는 메서드
    private func updateColorsForCurrentTheme() {
        // 다크 모드일 때와 라이트 모드일 때 다른 색상 적용
        if traitCollection.userInterfaceStyle == .dark {
            contentView.backgroundColor = .darkGray
            textLabel?.textColor = .white
        } else {
            contentView.backgroundColor = .lightGray
            textLabel?.textColor = .black
        }
    }
}

 

이런 식으로 코드가 생성될 수 있다. 

 

 

preferredLayoutAttributesFitting()

선호하는 레이아웃 속성에 맞추기 

preferred - 선호하는 

layout - 레이아웃 

Attributes - 속성, 특성, 설정값 

Fitting - 맞추다 조정하다 

호출시점

콜렉션 뷰나 테이블뷰가 셀의 크기를 결정할 때 호출 

사용하는 이유

셀의 최종크기를 결정하는데 사용. 특히 Auto Layout을 사용하는 경우 시스템이 제안한 크기 대신 원하는 크기를 지정할 수 있다. 

공식문서

https://developer.apple.com/documentation/uikit/uicollectionreusableview/preferredlayoutattributesfitting(_:)

 

preferredLayoutAttributesFitting(_:) | Apple Developer Documentation

Gives the cell a chance to modify the attributes provided by the layout object.

developer.apple.com

예제 코드

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    // 자동 크기 조정 대신 고정 크기 유지
    let attributes = super.preferredLayoutAttributesFitting(layoutAttributes)
    attributes.frame.size = CGSize(width: 80, height: 80)
    return attributes
}

 

그렇다면 내가 Auto Layout을 사용하는지 아닌지 어떻게 알 수 있을까? 

기본적으로 Auto Layout은 iOS 앱개발에서 표준이라 기본으로 설정되어 있다. 

그래도 확인하는 방법을 알아보자면 

스토리 보드에서 확인하는 방법

Main.storyboard 파일에서 컬렉션 뷰의 레이아웃 설정 확인 

automaticEstimatedItemSize="YES"

이렇게 입력되어 있다면 AutoLayout을 사용하고 있는 것이므로 고정크기 설정이 필요하면 preferredLayoutAttributesFitting()을 사용하면 된다. 

 

728x90

'IT > Swift 노트' 카테고리의 다른 글

UIDatePicker , Calender를 이용해 Label에 D-Day 표시하기  (1) 2025.04.21
037 Dictionary  (1) 2025.04.01
019 Nested Type 중첩타입  (0) 2025.03.31
018 formatting, locale  (0) 2025.03.31
036 Notification  (0) 2025.03.31