SwiftUI 고급 레이아웃 기법: 그리드와 커스텀 레이아웃

작성일 :

SwiftUI 고급 레이아웃 기법: 그리드와 커스텀 레이아웃

SwiftUI는 iOS 앱 개발자를 위한 매우 강력한 UI 프레임워크입니다. 이 문서에서는 SwiftUI의 고급 레이아웃 기법에 대해 다루며, 주로 그리드커스텀 레이아웃을 중심으로 설명합니다.

그리드 레이아웃

그리드 레이아웃은 다양한 크기의 셀을 유동적으로 배치하는 데 유용한 방법입니다. SwiftUI에서 그리드 레이아웃을 구현하는 데에는 LazyVGridLazyHGrid를 사용할 수 있습니다.

LazyVGrid

LazyVGrid는 수직 방향으로 그리드를 구성합니다. 기본적인 사용 예제는 다음과 같습니다:

swift
import SwiftUI

struct GridExampleView: View {
    let items = Array(1...100)
    let columns = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible())
    ]

    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns) {
                ForEach(items, id: \.self) { item in
                    Text("Item \(item)")
                        .frame(width: 100, height: 100)
                        .background(Color.blue)
                        .cornerRadius(8)
                }
            }
        }
    }
}

이 예제는 수직 그리드로 100개의 아이템을 3열로 배열합니다. GridItem.flexible()로 설정하면 각 셀의 너비가 유동적으로 조정됩니다.

LazyHGrid

LazyHGrid는 수평 방향으로 그리드를 구성합니다. 아래는 기본적인 사용 예제입니다:

swift
import SwiftUI

struct HorizontalGridExampleView: View {
    let items = Array(1...100)
    let rows = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible())
    ]

    var body: some View {
        ScrollView(.horizontal) {
            LazyHGrid(rows: rows) {
                ForEach(items, id: \.self) { item in
                    Text("Item \(item)")
                        .frame(width: 100, height: 100)
                        .background(Color.green)
                        .cornerRadius(8)
                }
            }
        }
    }
}

이 예제는 수평 그리드로 100개의 아이템을 3행으로 배열합니다. ScrollView.horizontal 파라미터를 통해 수평 스크롤이 가능하게 합니다.

커스텀 레이아웃

SwiftUI에서 제공하지 않는 특별한 레이아웃을 구현해야 하는 경우에는 커스텀 레이아웃을 작성할 수 있습니다. 이를 위해 CustomLayout 프로토콜을 사용할 수 있습니다.

CustomLayout 프로토콜

이 프로토콜은 자체 레이아웃 방식을 정의할 때 사용됩니다. 다음은 간단한 예제입니다:

swift
import SwiftUI

struct CustomLayoutExample: View {
    var body: some View {
        CustomStack {
            Text("First")
            Text("Second")
            Text("Third")
        }
    }
}

struct CustomStack<Content: View>: View {
    let content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        VStack {
            content
        }
    }
}

이 커스텀 스택은 전달된 뷰들을 세로로 렌더링합니다. @ViewBuilder는 뷰를 클로저로 받아서 제공합니다.

커스텀 레이아웃 만들기

좀 더 복잡한 커스텀 레이아웃을 만들려면 Layout 프로토콜을 구현해야 합니다. 아래는 예제입니다:

swift
import SwiftUI

struct CustomGridLayout: Layout {
    func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
        return CGSize(width: 200, height: 200)
    }

    func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
        for (index, subview) in subviews.enumerated() {
            let x = (index % 3) * 75
            let y = (index / 3) * 75
            subview.place(at: CGPoint(x: x, y: y), anchor: .topLeading)
        }
    }
}

struct CustomGridExample: View {
    var body: some View {
        CustomGridLayout {
            ForEach(0..<9) { index in
                Color.red.frame(width: 70, height: 70)
            }
        }
    }
}

이 예제에서 CustomGridLayout은 뷰를 3열의 그리드로 배치합니다. sizeThatFitsplaceSubviews 메서드를 통해 레이아웃의 크기와 뷰의 위치를 지정합니다.

이 문서에서 설명한 그리드 레이아웃커스텀 레이아웃 기법을 활용하여, SwiftUI에서 더욱 유연하고 강력한 사용자 인터페이스를 구현할 수 있을 것입니다.