「 SwiftUIのListとScrollViewの違いって? 」
「 どちらもそんなに変わらないのでは…? 」
SwiftUIには、スクロール画面を作ることができるという点で似た性質をもつ「List」と「ScrollView」があります。
一見同じように見えるこの二つの機能ですが、データの取り扱い方やメモリの使い方に違いがあり、用途によって使い分ける必要があります。
本記事では、ListとScrollViewの異なる点に加えて、どのように使い分けたら良いかをお話していきます!
[ 本記事はこんな人におすすめ ]
・SwiftUIを学びたい
・アプリでスクロール画面を作りたい
・ListとScrollViewの使い分けを知りたい
環境・バージョン
> Swift 5.7.2
> Xcode 14.2
> macOS 12.5 Monterey
Listは縦方向にのみ、画面スクロールが可能です。
デフォルトでセパレート線(区切り線)が引かれており、要素ごとに適度な余白が設けられています。
List機能について詳しくはこちらをご覧ください。
struct ContentView: View {
var body: some View {
List { // ⬅︎
ForEach(1..<100) { index in
Text("データ\(index)")
} // ForEach
} // List
} // body
} // View
Listのメモリ生成の特徴として、スクロールによって画面に表示されるタイミングでデータをメモリ上に生成します。
画面に表示される分だけメモリを生成するため、処理が軽いという特徴があります。
これは「遅延読み込み」とも呼ばれます。
ScrollViewは縦方向だけでなく、横、斜め、全方向への画面スクロールが可能です。
要素ごとのセパレート線(区切り線)はありません。
ScrollViewについて詳しくはこちらをご覧ください。
struct ContentView: View {
var body: some View {
ScrollView { // ⬅︎
ForEach(1..<100) { index in
Text("データ\(index)")
} // ForEach
} // ScrollView
} // body
} // View
ScrollViewのメモリ生成の特徴として、
画面表示時に、データ要素の全てをメモリ上に生成します。
一度に全てのデータを読み込むため、表示するデータ量が大きい場合は、読み込みに時間がかかる可能性があります。
「ScrollView」と「List」では、保持しているデータのメモリ生成(インスタンス化)のタイミングが異なります。
それぞれのメモリ生成のタイミングの違いを実験してみましょう。
メモリとは
コンピュータやスマートフォンのデータを記憶する領域のこと。
メモリ領域には制限があり、メモリを過度に圧迫すると処理が重くなったり、
アプリケーションが落ちる原因になる。
メモリ生成を実験するための下準備をしていきます。
新しくView構造体「RowText」を作成して、ContentView側から呼び出すコードを実装しました。
「row」とは、「1つ分、1つの」といった意味合いがあります。リスト内に表示される1つ分のテキスト要素と思っていただければ大丈夫です。
このように、Viewを呼び出す側は「親View」、呼び出される側は「子View」と呼ばれます。
今回の場合、親Viewは「ContentView」、子Viewは「RowText」ですね。
// 独自の子View
struct RowText: View {
// 画面表示されるテキストが格納される
let outputText: String
// ② イニシャライザー(最初に動くメソッド)
init(_ inputText: String) {
// プリント出力
print(inputText)
// 親Viewから渡された「inputText」を「outputText」に格納
outputText = inputText
}
var body: some View {
// ③ テキスト表示
Text(outputText)
} // body
} // View
struct ContentView: View {
var body: some View {
List {
ForEach(1..<100) { index in
// ① 子Viewを呼び出し
RowText("データ\(index)")
}
} // ScrollView
} // body
} // View
コード7〜13行目、initの中でprint出力を配置しています。
「init」内のコードは、Viewが生成された時に一番最初に実行されます。
この「RowText」が親Viewからの呼び出しによって生成された時に、print出力が実行されることで、どのタイミングで子Viewがメモリ生成されたのかがわかるという仕組みです。
…大丈夫でしょうか、ついて来れてますでしょうか?
構造体(struct)の呼び出しの仕組みに慣れていないと、少し難しく感じるかもしれません。
本記事では「ListやScrollViewが表示データ分のメモリを生成した時のタイミングがわかるようにしている」ということが分かれば大丈夫です◎
では、作成した子Viewを使ってメモリ生成のタイミングを実験していきます。
Listは、画面上に表示されているViewのみがメモリ上に生成されます。
画面スクロールに合わせて、表示に必要な分だけ順次にメモリ生成がされるので、大量のデータでも処理が軽いという特徴があります。これを「遅延読み込み」とも呼ばれます。
// 親View Listバージョン
struct ContentView: View {
var body: some View {
List {
ForEach(1..<100) { index in // ⬅︎
// 子Viewを呼び出し
RowText("データ\(index)")
}
} // ScrollView
} // body
} // View
では、上記のコードをシミュレータ「command + R」で確認してみましょう。
画面のスクロールに合わせて、新しく表示されるデータ範囲に合わせてメモリが生成されていることがわかります。
一度に全てのデータを読み込まず、ユーザの操作に合わせてメモリ生成する
「遅延読み込み」が確認できますね。
ScrollViewは、画面表示時に全てのViewがメモリ上に生成されます。
コードとしては、「List」部分を「ScrollView」に書き換えたのみです。
struct ContentView: View {
var body: some View {
ScrollView {
ForEach(1..<100) { index in
// 子Viewを呼び出し
RowText("データ\(index)")
} // ForEzch
} // ScrollView
} // body
} // View
では、こちらもシミュレータ「command + R」で確認していきます。
今回はシミュレータ起動時から挙動を見てみましょう。
シミュレータによって画面が描画された時点で、画面に表示されていない箇所も含めて、(1..<100)までの全てのデータが全てメモリ生成されていることがわかります。
ScrollViewは描画時に自身が保持するデータ全てをメモリ生成するため、たくさんのデータ数を表示するのにはあまり向かないということですね。
✅Check!!!
– ScrollViewでも遅延読み込みが可能に –
Swiftは日々技術が刷新されています。
iOS14から、ScrollViewでも「LazyVStack」「LazyHStack」を併用することで、遅延読み込みが実装できるようになりました。
Lazyとは「怠惰」といった意味があり、遅延のニュアンスを指しています。
ScrollViewが保持しているデータを「LazyVStack」で囲みます。
struct ContentView: View {
var body: some View {
ScrollView {
LazyVStack { // ⬅︎
ForEach(1..<100) { index in
RowText("データ\(index)")
}
} // LazyVStack
} // ScrollView
} // body
} // View
これによって、ScrollViewでも遅延読み込みが実装できます。
ここまでご紹介してきた各機能を踏まえた上で、「ScrollView」と「List」をどう使い分けていくかをまとめていきます。
以下はCodeCandyのYouTube動画での参照表です。
これらを基準にして機能を選定しましょう。
例えば、アプリに「遅延読み込み」を実装したいとします。
iOS14以前のバージョンもサポートするアプリだった場合、前述で解説した「LazyVStack」や「LazyHStack」は使用できません。よって、「List」を用いるのが望ましいでしょう。
以上、SwiftUIの機能「List」と「ScrollView」それぞれの特徴と使い分けについてでした。
・Listは画面表示に合わせてメモリを生成する(遅延読み込み)
・ScrollViewは一度に全てのデータをメモリ生成する
・LazyVStack, LazyHStackを使うことで、ScrollViewでも遅延読み込みが可能 (iOS14〜)
実装したい機能や画面デザイン、アプリの仕様に合わせて、適切に使い分けていきましょう◎
\ SHARE /
アプリ開発が学べる勉強会を開催中!
CodeCandyではアプリ開発を学ぶための勉強会を定期開催しています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。
徹底した基礎学習からマスターするiPhoneアプリ開発集中オンライン講座開講!
本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!
まずは、現役エンジニアに相談できる無料相談をご利用ください。
2022年2月よりSwift学習を始め、4月からiOSアプリ開発オンラインスクール「CodeCandy」にてアプリ開発を学ぶ。 2023年10月に個人開発アプリ「unico」をリリース。現在はアプリの機能アップデートをしながら、スクール運営の技術ブログの執筆や、出版書籍の入稿チェック・デバッグにも携わる。