はじめに
Swift歴3ヶ月の新米プログラマーのメモ。
ハマったポイント
ユーザーの入力値から特定の文字列だけを抽出する非同期関数を作り、ボタンを押すとその関数の抽出結果をシートに渡して表示させるコードを書いたら、抽出結果が渡る前にシートが表示されてしまった。
原因
シートの表示トリガーを「isPresented」にしていた。
何が違うのか
そもそも値渡しをするなら、使い分け的に「item」の方を使うべきだったのだが、それは一旦置いておいて
関数の定義を見てみると、@escaping
の引数に違いがある。
isPresented
public func sheet<Content>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping () -> Content) -> some View where Content : View
item
public func sheet<Item, Content>(item: Binding<Item?>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping (Item) -> Content) -> some View where Item : Identifiable, Content : View
今回の場合、"入力値から特定の文字列だけを抽出する処理"が非同期なため、「isPrsented」にすると抽出結果が渡されてからシートが表示されるか、シートが表示されてから抽出結果が渡されるかが未確定になってしまう。
「item」にすれば、抽出結果の値が入ることによってシートが表示されるので、抽出結果が確実に渡されることを証明することができる。
ちなみに
どういう原理かはわからないが、ボタンアクションにキーボードを閉じる処理を加えても、ちゃんと抽出結果が渡ってからシートが表示されるようになった。
参考