본문 바로가기
iOS

[SwiftUI] GridView 만들기

by 워뇨옹2 2024. 9. 10.
728x90
반응형

개요

이번 포스팅은 따로 길게 설명하기보다 바로 코드로 넘어가도록 하겠다.

GridListView 코드


import SwiftUI


struct GridListView<Content: View>: View {
    private let columns: [GridItem]
    private let content: (CGFloat) -> Content
    init(
        count: Int = 3,
        spacing: CGFloat = 10,
        _ content: @escaping (CGFloat) -> Content
    ) {
        self.columns = Array(repeating: GridItem.init(.flexible(), spacing: spacing), count: count)
        self.spacing = spacing
        self.content = content
    }
    @State private var width: CGFloat = 0
    
    private var spacing: CGFloat = 10
    private var columnsCount: CGFloat {
        CGFloat(columns.count)
    }
    
    var body: some View {
        VStack(spacing: 0) {
            LazyVGrid(columns: columns, spacing: spacing) {
                let itemWidth = max((width - (spacing * (columnsCount - 1))) / CGFloat(columnsCount), 0)
                content(itemWidth)
            }
            GeometryReader { proxy in
                Color.clear
                    .frame(height: 1)
                    .onAppear {
                        self.width = proxy.size.width
                    }
                    .onChange(of: proxy.size.width) { newValue in
                        self.width = newValue
                    }
            }
        }
    }
}

#Preview {
    GridListView() { itemWidth in
        ForEach(0...10, id:\.self) { i in
        	Text("\(i)")
            	.frame(width: itemWidth, height: itemWidth)
        }
    }
}

 

사용법

기존에 GridView를 만들때마다 너비 계산때문에 여간 골치아픈게 아니었는데, 이 참에 블로그 뒤져보면서 하나하나 긁어와 이렇게 컴포넌트를 만들었다. Vertical로 만들어져있으며, 스크롤뷰로 감싸줘야 한다.

 

먼저 생성자쪽을 보면 총 3개의 인자를 받는다.

count는 한 행에 몇개의 뷰가 들어갈지 정해준다.

spacing은 한 행에서 다음 행까지의 간격 및 각 열끼리의 간격을 의미한다.

content는 View를 받아오는건데, ForEach를 사용해서 여러개의 아이템을 처리하면 된다.

 

혹여나 하드코딩으로 몇개만 집어넣을 경우 Group을 사용해서 넣어주면 된다.

 

 

 

728x90
반응형