3
4

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.

SwiftUIのListのfilterを高速化する

Posted at

開発環境

  • MacBookAir 2019
  • macOS Catarina 10.15
  • Xcode 11.2.1
  • SwiftUI

概要

Listのfilterで要素数が500以上の時、異常に挙動が遅くなる現象を解決できたので私が行った方法を備忘録的にまとめます。

#ソースコード

struct JsonData: Codable, Equatable,Identifiable{
    var id: Int
    var itemName: String
    var itemPrice: Int
    ・・・
}
修正前
@EnvironmentObject var jsonData: JsonData

List {
    ForEach(jsonData.filter{$0.hasPrefix(searchText)}, id:\.self) {item in
        Text(item)
    }
}

searchText@Stateで定義しており、ここに検索バーに入力された文字が格納されています。searchTextの値が変更されるとその都度Listの中身が更新されます。

この状態でビルドすると、
3.04.39.png
非常にラグがありますが一応は検索できます(1文字入力すると数秒固まる)。
これはおそらくjsonDataに格納されているデータ数が多いとfilterの処理が律速段階となってしまうためだと思われます。

#解決策
StackOverflow :How do I efficiently filter a long list in SwiftUI?

この投稿を参考に、Listを毎回作り替えることで高速化が実現できました。

修正後
@EnvironmentObject var jsonData: JsonData

if searchText==""{
    nonFiltered()
}else{
    filtered()
}

////////////////////////////
struct filtered: View {
    @EnvironmentObject var jsonData: JsonData
    var body: some View {
        List {
            ForEach(jsonData.filter{$0.hasPrefix(searchText)}, id:\.self) {item in
                Text(item)
            }
        }
    }
}
struct nonFiltered: View {
    @EnvironmentObject var jsonData: JsonData
    var body: some View {
        List {
            ForEach(jsonData) {item in
                Text(item)
            }
        }
    }
}

驚くほど劇的にラグが改善しました。めちゃめちゃヌルヌル動作します。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?