기어가더라도 제대로

[SwiftUI-기초] Custom Container 본문

SwiftUI - 기초

[SwiftUI-기초] Custom Container

Damagucci-juice 2022. 10. 16. 09:00
  • 커스텀 modifier 에 이은 커스텀 컨테이너입니다. 
  • VStack, HStack, ZStack, 과 같은 것을 만들어 볼겁니다.
  • 제가 최근에 달력을 만들일이 있었어요. UIKit 에서는 UICollectionView 를 사용했었는데,
  • SwiftUI 엔 마땅한게 없더라구요. 16 버전에서 Calendar 기능이 추가되긴 하는데, iOS 15버전에선 어렵더라구요
  • 한번 calendar 를 사용하기 위한 Grid 컨테이너 뷰를 만들어보죠 !

이게 컨테이너의 특성상 Content를 받아야합니다. 

그래서<> 내부는 받을 Content  를 제네릭 하게 View 타입이라고 선언하는 것이구요. 

GridStack 자체도 물론 View 타입이라고 말합니다. 

Body 도 완성을 해봅시다. 

이중 ForEach 문으로 Grid 형태를 짜고 있네요. 

사용법

struct ContentView: View {
    var body: some View {
        GridStack(rows: 4, columns: 4) { row, col in
            Text("R\(row) C\(col)")
        }
    }
}

이렇게 사용할 수 있네요. 

내부에 다른 컨테이너를 넣을 수도 있고요 .

근데 우리 버튼에 Label 달 때 따로 HStack 사용하지 않아도 좌우로 배치되는 경험이 있잖아요.

우리 커스텀 컨테이너에서도 그런 기능을 마련해줘볼까요? 

@ViewBuilder 를 이용하기 

위에서 생성한 GridStack의 content 프로퍼티에 @ViewBuilder attribute 를 추가해줍시다. 

이러면 GridStack 을 구현할 때 내부 콘텐츠들에 대해서 암시적으로 HStack 에 넣은 효과를 줍니다. 

GridStack(rows: 4, columns: 4) { row, col in
    Image(systemName: "\(row * 4 + col).circle")
    Text("R\(row) C\(col)")
}

@ViewBuilder 란? 

View 의 definition을 보면 이렇게 나와있습니다.

Swift는 Body 속성에 내부에 암시적으로 @ViewBuilder attibute 를 추가하는데요.

이 속성은 내부적으로 다수의 View 를 하나의 TupleView 컨테이너로 묶어주는 기능을 한다고 합니다. 

그래서 우리가 Content 속성에 Container 로 묶지 않고 이미지와 텍스트를 넣어도 내부적으로는

TupleView를 구성해서 HStack 인 것처럼 사용한다고 합니다. 

Comments