2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ScrollView + LazyVGrid / LazyHGrid で固定列 + スクロール列のグリッドを作成する

Last updated at Posted at 2021-12-12

SwiftUIにて、表示固定部分と横スクロール部分を水平に配置し、
全体としては縦スクロールするグリッドを作成する。
縦2.png
sample3.gif
実装コードはこちら。
全体の ScrollView を [.vertical] として縦スクロールさせつつ、
入れ子にした ScrollView は [.horizontal] として横スクロールさせています。

ContentView.swift
import SwiftUI

var columnWidth: CGFloat = 60 // 列幅
var rowHeight: CGFloat = 60 // 行高さ
var rowCount: Int = 50 // 表示行数


struct ContentView: View {
    // 大文字アルファベットの配列
    // ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

    let Alphabets = (65...90).map{ String(Character(UnicodeScalar($0)!)) }
    
    var body: some View {
        ScrollView([.vertical]) { // 全体としては縦スクロールさせる
            HStack {
                // タイトル列
                ScrollView {
                    ForEach(1..<rowCount + 1) { rowNum in
                        TitleColumns(rowNum: "\(rowNum)")
                    }
                }
                .frame(maxWidth: columnWidth) // 列幅
                
                // データ列
                ScrollView([.horizontal]) { // データ列は横スクロールさせる
                    ForEach(1..<rowCount + 1) { rowNum in
                        DataColumns(rowNum: "\(rowNum)", items: Alphabets)
                    }
                }
                .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
            .padding(.horizontal, 20)
            .padding(.vertical, 20)
        }
    }
}

// タイトル列
struct TitleColumns: View {
    var rowNum: String
    
    var body: some View {
        LazyVGrid(
            columns: Array(
                repeating: .init(),
                count: 1 // 列数
            )
        ) {
            ZStack {
                Rectangle()
                    .frame(height: rowHeight) // 行高さ
                    .foregroundColor(.green)
                Text("\(rowNum)")
                    .foregroundColor(.white)
            }
        }
    }
}

// データ列
struct DataColumns: View {
    var rowNum: String
    var items: [String]
    
    var body: some View {
        LazyVGrid(
            columns: Array(
                repeating: .init(.fixed(columnWidth)), // 列幅
                count: items.count
            )
        ) {
            ForEach(items, id: \.self) { item in
                ZStack {
                    Rectangle()
                        .frame(height: rowHeight) // 行高さ
                        .foregroundColor(.gray)
                    Text("\(item)\(rowNum)")
                        .foregroundColor(.white)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
            .previewInterfaceOrientation(.portrait)
    }
}

大文字アルファベットの配列の作成は以下を引用させていただきました。

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?