4
2

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のpickerを動的に書き換える技

Posted at

環境 xcode11.6
swiftUI

あまり日本語でこの問題に関して言及する記事がなかったので書いてみました。

Pickerに表示したい要素をarrayで定義しておいてForEachで動的に表示したいことってありますよね?うん?
ただ、動的にarrayの要素を削除したりしてpcikerを動かそうとすると
Fatal error: Index out of range
となります。
なぜなら、pickerはそのなかのarrayが変化したことを検知できないのです!!
なので、検知させましょう。
ということで、方法は下記のようにPickerに.id()を追加します。

Picker(selection: selectd, label: Text("文字色")) {
                ForEach(0..<array.count, id: \.self){ id in
                    self.array[id]
                        .tag(self.array[id])
                }
            }
            .id(self.uuid)

こうすると、idの引数に渡したself.uuidが更新されたときに、pickerがreloadされて動的に削除したり追加した要素を正しく反映できます。
ちなみに、Pickerのselectionにわたすselectedは、下記のようにカスタムBindingを用意して、setされたらuuidを更新するようにしたりすればいいでしょう。

let selectd = Binding(
            get: {  },
            set: {
                self.uuid = UUID()
            }
        )

こうしてまた迷えるswiftUIエンジニアを救ってしまった。

あ、参考情報はこちらです。

まさにこれで解決できました。
https://stackoverflow.com/questions/60082411/swiftui-hierarchical-picker-with-dynamic-data-crashes

カスタムバインディングについて。
https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-custom-bindings

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?