LoginSignup
6
6

More than 3 years have passed since last update.

【SwiftUI】Listを横方向にスクロールさせる

Last updated at Posted at 2021-03-13

SwiftUIのListで、Listを横方向(水平方向)にスクロールさせるコードの紹介です。

sample1

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の幅の自動設定がうまくできない
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6