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
반응형
'iOS' 카테고리의 다른 글
| [SwiftUI] onAppear는 화면이 그려진 뒤에 불리는 함수가 아니다? (0) | 2024.09.25 |
|---|---|
| [SwiftUI] ViewModifier? Custom ViewModifier 만들기 (1) | 2024.09.11 |
| [SwiftUI] SafeArea height 구하기 (0) | 2024.09.09 |
| [Swift] Firebase Crashlytics 적용하기 (2) | 2024.09.04 |
| [Swift] String Localization (0) | 2024.07.09 |