💬

【SwiftUI入門】ListとSectionの繰り返し表示について

2023/09/02に公開

超初心者向けです。自分のための備忘録でもあります。

完成イメージ

作りたいもの↓

リストをいくつか小分けにして、それぞれの上にタイトル的なものを表示して、これを自動で複数個表示(foreachで)したい。

結論

List{}の中にForEach{}を書き、
そのForEach{}の中にSection{}を書き、
そのSection{}の中に表示したい項目を自由に並べる。

Sectionでheaderを指定する。

var body: some View {
        VStack {
            List {
                ForEach(kabuInfos) { kabuInfo in
                    Section(header:Text(kabuInfo.name)) {
                        Text(kabuInfo.code)
                        Text("\(String(format:"%.2f", kabuInfo.currentPrice))")
                    }
                }
            }
            .listStyle(InsetGroupedListStyle())
            Text("This is SecondView.")
            
            Spacer()
        }
}

つまずいたこと1

分けたかったものが全部繋がっちゃった。

Section{}内で繰り返し表示してしまっていた。
→行が複数並ぶ単位が「Section」なんだと学んだ。そりゃ一緒に行表示されてしまうわけだ。

var body: some View {
        VStack {
            List {
	        Section {
		    ForEach(kabuInfos) { kabuInfo in
		        Text(kabuInfo.code)
		        Text("\(String(format:"%.2f", kabuInfo.currentPrice))")
		    }
		}
            }
            .listStyle(InsetGroupedListStyle())
            Text("This is SecondView.")
            
            Spacer()
        }
}

ちなみにこのときはまだSectionのheaderを入れていない。(Sectionのタイトル的なもの)

つまずいたこと2

じゃあSectionの外でForEach表示すればいいのか、ってことで試しにVStack{}の真下に入れてみた。

var body: some View {
        VStack {
	    ForEach(kabuInfos) { kabuInfo in
                List {
	            Section {
		        Text(kabuInfo.code)
		        Text("\(String(format:"%.2f", kabuInfo.currentPrice))")
		    }
		}
            }
            .listStyle(InsetGroupedListStyle())
            Text("This is SecondView.")
            
            Spacer()
        }
}

そしたらこうなった。惜しいけど思ってるのと違う。

List{}ごとForEachで繰り返し表示してしまったようだ。
「なんか思ってたんと違う」ってなったのは、List{}の外にForEach{}を書いていたせい。

完成イメージみたいにしたいなら、繰り返すのはListではなくSection!

で結局

紆余曲折あって、List{}の中かつSection{}の外 という結論に行き着き、こうなる。

var body: some View {
        VStack {
            List {
                ForEach(kabuInfos) { kabuInfo in
                    Section {
                        Text(kabuInfo.code)
                        Text("\(String(format:"%.2f", kabuInfo.currentPrice))")
                    }
                }
            }
            .listStyle(InsetGroupedListStyle())
            Text("This is SecondView.")
            
            Spacer()
        }
}

最後にSectionにタイトルをつける。

Section(header:Text("title")) {
    ...
}

私は、構造体の配列ごとにタイトル(ヘッダ?)を決めたかったので、構造体からnameを取得して表示。

完成版がこう。

var body: some View {
        VStack {
            List {
                ForEach(kabuInfos) { kabuInfo in
                    Section(header:Text(kabuInfo.name)) {
                        Text(kabuInfo.code)
                        Text("\(String(format:"%.2f", kabuInfo.currentPrice))")
                    }
                }
            }
            .listStyle(InsetGroupedListStyle())
            Text("This is SecondView.")
            
            Spacer()
        }
}

Discussion