【SwiftUI】List를 가로로 스크롤시킨다

11192 단어 SwiftSwiftUI
SwiftUI의 List에서 List를 가로 방향(수평 방향)으로 스크롤시키는 코드의 소개입니다.



SwiftUI List Horizontal 」등으로 검색하면
ScrollView (.horizontal) {
     HStack {
         ...
     }
}

와 같은 ScrollView 를 사용한 것이 많이 히트합니다만, 이 경우는 거대한 데이터의 경우에 문제가 나옵니다(Row의 데이터가 최초로 모두 작성되어 버리기 때문입니다).
그래서 ListrotationEffect 로 90도 회전시켜 가로 스크롤을 실현합니다.

환경


  • Swift: 5.3.2
  • Xcode: 12.4 (12D4e)
  • macOS: Big Sur 11.1 (20C69)

  • 코드



    ContentView.swift
    import SwiftUI
    
    struct ContentView: View {
        var body: some View {
            VStack {
                ItemList(items: (0..<100).map { ItemData(index: $0) })
                    .frame(height: 100)
                ItemList(items: (500..<600).map { ItemData(index: $0) })
                ItemList(items: (1000..<1100).map { ItemData(index: $0) })
            }
        }
    }
    
    struct ItemData {
        var index = 0
        var check = false
    }
    
    struct ItemList: View {
        @State var items: [ItemData]
    
        var body: some View {
            GeometryReader { geo in
                List(0..<items.count) { i in
                    ItemRow(item: $items[i])
                        .frame(height: 100)
                        .contentShape(Rectangle())
                }
                .frame(width: geo.size.height, height: geo.size.width)
                .rotationEffect(.degrees(-90), anchor: .bottomLeading)
                .transformEffect(.init(translationX: geo.size.width, y: 0))
                .scaleEffect(x: 1, y: -1)
            }
        }
    }
    
    struct ItemRow: View {
        @Binding var item: ItemData
    
        var body: some View {
            GeometryReader { geo in
                ZStack {
                    Color.blue.opacity(item.check ? 0.5 : 0.3)
                        .cornerRadius(8)
                    Text("\(item.index)")
                }
                .frame(width: geo.size.height, height: geo.size.width)
                .rotationEffect(.degrees(90), anchor: .topTrailing)
                .transformEffect(.init(translationX: 0, y: geo.size.height))
                .scaleEffect(x: -1, y: 1)
                .onTapGesture {
                    item.check.toggle()
                }
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    

    리포지토리



    문제점


  • 문자 수로 Row 너비를 자동으로 설정할 수 없습니다
  • 좋은 웹페이지 즐겨찾기