AutoOpenTextField.swift

こんにちは。EveryDaySoft代表の永田です。

目的

SwiftUIでは画面が開いた際に、自動でキーボードを開く処理が時間を遅らせて開く方法しか簡単な方法がないという情報共有があり、調査しました。

DispatchQueue.main.asyncAfter(deadline: .now() + 1)

最近のXcodeではOne of the two will be used. Which one is undefined.のログが出てしまうのが気になります。

環境
Xcode13.1 iOS15.0

対応挙動

ソース

https://gist.github.com/daisukenagata/1253ea3c6e999166a12f4abf45fb001d

iOS15から、@FocusStateという状態が変化すると、.focused()の箇所が実行される仕組みが追加されました。SwiftUIでは起動時にonAppear内で状態を変更しても動作しませんでした。UIkitではViewDidAppearの処理がないのです。試行錯誤の結果、変数自体にdidSetを設定し、値が変わったら非同期で状態を変化させる仕組みを実装した所、上手くいきました。

import SwiftUI

@available(iOS 15.0, *)
struct AutoOpenTextField: View {

    @State private var name = ""
    @FocusState var isFocused: Bool {
        didSet {
            DispatchQueue.main.async {
                isFocused = true
            }
        }
    }

    var body: some View {
        TextField("Name", text: $name)
            .focused($isFocused)
            .onAppear {
                isFocused = false
            }
    }
}

@available(iOS 15.0, *)
struct AutoOpenTextField_Previews: PreviewProvider {
    static var previews: some View {
        AutoOpenTextField()
    }
}

貴重なお時間、お読みくださいまして誠にありがとうございます。