概要
Listに対してPull to refresh(画面を下に引っ張った時に何かしらの処理を行うこと。gifアニメーション参照)を実装しようとした時に、ちょっとした勘違いから誤った実装方法を試してしまい、時間を使ってしまったので自戒を込めて記事を書きます。
詳細
事の経緯としては、
1.Pull to refreshの実装方法を調べた時にたまたま出てきた情報を鵜呑みにしてscrollviewとrefreshableモディファイアはセットで使わなければならないと思い込んでいた(pull to refreshにはスクロールする動きが必要だと思っていたのもあり)
2.いくらScrollviewとセットでListを使用しても画面が表示されるおかしいと思い始める
3.Listで実装している例を発見し、試してみたところ、無事解決!
という流れです。
以下では正しい実装例と私が間違って実装していた方法の両方を説明します。
正しい実装例
まず、実装例のコードですが、以下のように書きます。
至ってシンプルで、List
に対して.refreshable
を付与し、クロージャ内で処理を記述するという流れです。
これはForm
などの違う部品に対しても付与可能です。
より詳しい仕様について知りたい場合は、備考欄にある公式ドキュメントを参考にしてください。
import SwiftUI
struct ContentView: View {
let fruits:[String] = [
"りんご",
"スイカ",
"みかん"
]
var body: some View {
List{
ForEach(0 ..< fruits.count){ index in
Text(fruits[index])
}
}
.refreshable {
// リフレッシュ時の処理を書く
}
}
}
ただ、私の場合には誤って以下のように記述をしてしまい、そもそもViewが正しく描画されない現象が起こりました。
import SwiftUI
struct ContentView: View {
let fruits:[String] = [
"りんご",
"スイカ",
"みかん"
]
var body: some View {
+ ScrollView{
List{
ForEach(0 ..< fruits.count){ index in
Text(fruits[index])
}
}
.refreshable {
// 処理
+ }
}
}
}
上記のようにScrollView
の中にList
を記述すると以下のように画面が真っ白な状態になります。

この状態では画面を下に引っ張ったとしても何も画面が反応しない状態になります。
View Hierarchyで画面を参照してみると、以下のような構造になっており、そもそもView以降の要素が表示されていないことが分かります。
(View Hierarchyで確認した構成要素。SystemScrollView
が一番上に表示されている構成要素になっており、List以降の要素が存在しない状態になっている。)
このことから、ScrollView
の中にList
を記述するのはあまり好ましくない使用法であると考えられます。
結論
-
refreshable
はPull to refreshを仕掛けたい要素に対して付与するモディファイア - 原則、
ScrollView
の中にList
を書くのは避けるべき
備考
公式ドキュメント
refreshable(action:)