SwiftUIのListは、データなどをリスト表示させる場合便利なコントロールです。このListはSectionを持たせることができ ヘッダー・フッターをつけることもできます。LIstのシンプルな記述方法は下記です。
struct TListBox: View { var body: some View { List{ Text("アイテム1") Text("アイテム2") } } }
このコードの場合Textを個別に入れています。この記述方法ではList内のアイテムが多い場合対応できません。例えば100個のリストを作成する場合は下のように記述できます。
struct TListBox: View { var body: some View { List(0..<100){ Text("アイテム\($0 + 1)") } } }
Listのカッコ内に、Range式を入れることができます。Rangeは下記のように記述もできます。
var range: Range = 0..<10
RangeはisEmpty, clamped, overlapsなどの機能も持っています。List内でForEachが記述できるのでRangeを使うことが可能です。
struct TListBox: View { var forEachText = ForEach(0..<10){ Text("\($0 + 1)") } var body: some View { List{ self.forEachText } } }
ForEachをforEachText変数に入れていますが、Listの中に直接書くこともできます。
Listに配列などが入れば便利なのですが、「List([1,2])」このようには記述できないようです。
Initializer 'init(_:rowContent:)' requires that 'Int' conform to 'Identifiable'
配列の場合、下のコードのように id指定が必要です。
List([1,2,3], id: \.self){ Text("\($0)") }
下のようなIdentifiable が付いた構造体の場合、配列をそのままList()に設定することが可能です。
struct TListItem: Identifiable { var id: Int init(_ i: Int) { id = i } } struct TListBox: View { var items: Array<TListItem> = [TListItem(1),TListItem(2)] var body: some View { List(items){ Text("アイテム\($0.id)") } } }
上のコードは、Identifiableを付けたTListItemの配列をList()内で使っています。
List内にはSectionを使いヘッダーとフッターをつけることもできます。
struct TListBox: View { var forEachText = ForEach(0..<2){ Text("\($0 + 1)") } var body: some View { List{ ForEach(0..<2){ Section(header: Text("ヘッダー\($0 + 1)"), footer: Text("フッター\($0 + 1)")){ self.forEachText } } } } }
List()のカッコ内に構造体配列の変数を設定することで動的にListを更新できます。下のコードは、Timerを使ってデータ内容を更新させListに反映させる例です。
struct TListItem: Identifiable { var id: Int var t: String init(_ i: Int, _ s: String) { id = i t = s } } struct TListBox: View { @State var listItems: [TListItem] = []; @State var count: Int = 0 @State var timer1: Timer? var body: some View { List(listItems){ Text($0.t) }.onAppear(){ self.timer1?.invalidate() self.timer1 = Timer.scheduledTimer(withTimeInterval: 0.8, repeats: true) {_ in if (self.count <= 100) { let df = DateFormatter() df.dateFormat = "🕐 mm分ss秒SSS" self.listItems.append(TListItem(self.count, df.string(from: Date()))) self.count += 1 } } } } }
上のように、List内アイテム間に線が入ってしまいます。これを回避するにはonAppear時に「separatorStyle = .none 」を設定します。
List(listItems){ Text($0.t) }.onAppear { UITableView.appearance().separatorStyle = .none } .onDisappear { UITableView.appearance().separatorStyle = .singleLine }