Help us understand the problem. What is going on with this article?

swiftUIのpickerを動的に書き換える技

環境 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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした