SwiftUI Horizontal List 구현하기

작성일 :

SwiftUI Horizontal List 구현하기: ScrollView와 LazyHStack 활용

SwiftUI에서 데이터를 수평으로 스크롤 가능한 리스트 형태로 표시하는 것은 유용한 기능입니다. 그러나 기본 제공되는 List 뷰는 수평 방향을 지원하지 않습니다. 대신, ScrollViewLazyHStack을 결합하여 수평 리스트를 구현할 수 있습니다. 이 글에서는 SwiftUI에서 horizontal list를 구현하는 방법과 커스터마이징, 고급 기능을 살펴보겠습니다.

SwiftUI List와 ScrollView + LazyHStack 비교

List는 SwiftUI에서 가장 많이 사용되는 데이터 디스플레이 컴포넌트 중 하나입니다. List는 세로 스크롤만을 지원하며, 기본적으로 수평 스크롤을 제공하지 않습니다. 반면에, ScrollViewLazyHStack을 사용하면 수평 스크롤이 가능한 리스트를 쉽게 구현할 수 있습니다.

List의 제한 사항

  • 수평 스크롤 미지원: List는 기본적으로 수평 방향으로 스크롤할 수 없습니다.
  • 커스터마이징 제약: List는 정해진 레이아웃과 스타일을 따르기 때문에, 복잡한 커스텀 레이아웃을 구현하기 어렵습니다.

ScrollView와 LazyHStack 사용하기

ScrollViewLazyHStack을 사용하면 수평 스크롤이 가능한 리스트를 유연하게 구현할 수 있습니다. LazyHStack은 필요한 아이템만 로드하여 성능을 최적화하는 데 도움을 줍니다.

기본 사용법

아래는 ScrollViewLazyHStack을 사용하여 수평 리스트를 구현하는 간단한 예제입니다:

swift
struct HorizontalListView: View {
    let items = Array(1...20).map { "Item \($0)" }

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack {
                ForEach(items, id: \.self) { item in
                    Text(item)
                        .padding()
                        .background(Color.blue)
                        .cornerRadius(8)
                }
            }
            .padding(.horizontal)
        }
    }
}

커스터마이징

ScrollViewLazyHStack을 사용하면 각 아이템의 레이아웃과 스타일을 자유롭게 커스터마이징할 수 있습니다.

아이템 레이아웃

각 아이템의 레이아웃을 커스터마이징하여 더욱 복잡하고 매력적인 UI를 만들 수 있습니다.

swift
struct CustomItemView: View {
    var item: String

    var body: some View {
        VStack {
            Image(systemName: "star")
                .resizable()
                .frame(width: 50, height: 50)
                .padding()
            Text(item)
                .font(.headline)
        }
        .background(Color.gray.opacity(0.3))
        .cornerRadius(10)
        .padding(5)
    }
}

struct HorizontalListView: View {
    let items = Array(1...20).map { "Item \($0)" }

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack {
                ForEach(items, id: \.self) { item in
                    CustomItemView(item: item)
                }
            }
            .padding(.horizontal)
        }
    }
}

고급 기능

무한 스크롤 구현

무한 스크롤을 구현하려면 추가 데이터를 동적으로 로드하여 리스트에 추가하는 기능이 필요합니다.

swift
class InfiniteScrollViewModel: ObservableObject {
    @Published var items = [String]()
    private var isLoading = false

    init() {
        loadMoreItems()
    }

    func loadMoreItems() {
        guard !isLoading else { return }
        isLoading = true
        DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
            let moreItems = (self.items.count..<self.items.count + 20).map { "Item \($0)" }
            DispatchQueue.main.async {
                self.items.append(contentsOf: moreItems)
                self.isLoading = false
            }
        }
    }
}

struct InfiniteHorizontalListView: View {
    @StateObject private var viewModel = InfiniteScrollViewModel()

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack {
                ForEach(viewModel.items, id: \.self) { item in
                    Text(item)
                        .padding()
                        .background(Color.blue)
                        .cornerRadius(8)
                        .onAppear {
                            if item == viewModel.items.last {
                                viewModel.loadMoreItems()
                            }
                        }
                }
            }
            .padding(.horizontal)
        }
    }
}

섹션 및 그룹화된 리스트

섹션 헤더를 추가하여 데이터를 그룹화할 수 있습니다.

swift
struct SectionedHorizontalListView: View {
    let sections = [
        ["Header 1": ["Item 1", "Item 2"]],
        ["Header 2": ["Item 3", "Item 4"]]
    ]

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(alignment: .top) {
                ForEach(sections, id: \.keys.first!) { section in
                    VStack {
                        Text(section.keys.first!)
                            .font(.headline)
                            .padding()
                        LazyHStack {
                            ForEach(section.values.first!, id: \.self) { item in
                                Text(item)
                                    .padding()
                                    .background(Color.blue)
                                    .cornerRadius(8)
                            }
                        }
                    }
                    .padding(.horizontal)
                }
            }
        }
    }
}

성능 최적화

LazyHStack을 사용하면 필요한 뷰만 로드하여 메모리 효율성을 극대화할 수 있습니다. 또한, 많은 데이터를 처리할 때 불필요한 뷰 로딩을 방지하여 성능을 향상시킬 수 있습니다.

결론

SwiftUI에서 수평 스크롤 리스트를 구현하려면 List 대신 ScrollViewLazyHStack을 사용해야 합니다. 이러한 접근 방식은 유연성과 성능 최적화를 제공하며, 다양한 커스터마이징과 고급 기능을 활용할 수 있습니다. 이 글에서 소개한 방법을 통해 SwiftUI에서 수평 스크롤 리스트를 효과적으로 구현할 수 있을 것입니다.