web-dev-qa-db-ja.com

SwiftおよびTextField文字列からモデルのパブリッシュされたオプションのIntegerプロパティへのSwiftUIバインディング

SwiftとSwiftUIは初めてですが、@ Published intValueオプションのモデルと、テキスト/文字列プロパティがモデルのintValueに双方向にバインドされているTextFieldのビューがあります。文字列がモデルの有効な整数に変換されるように、有効なテキストエントリを確認する必要があります。SwiftUIでこれを処理するための推奨されるアプローチは何ですか?コードは以下のようになります...

//Model
class AppModel:ObservedObject {
 @Published
 var intValue: Int? = 5
}

//View
@ObservedObject
 var appModel = AppModel.shared

TextField("", text: $appModel.intValue)
                    .keyboardType(.numberPad)

更新されたサンプルコード...

///////////
import SwiftUI

class Model: ObservableObject {
    static var shared: Model = Model()

    @Published
    var number: Int = 0

    init(){}

}

struct ContentView: View {
    var body: some View {
        TextFieldFormatter()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


struct TextFieldFormatter: View {
    @ObservedObject
    var model: Model = Model.shared

    @State private var number: Int = 0


    let formatter: NumberFormatter = {
        let numFormatter = NumberFormatter()
        numFormatter.numberStyle = .none
        return numFormatter
    }()

    var body: some View {
        VStack {
            Text("State").onTapGesture {
                self.endEditing()
            }
            TextField("int", value: $number, formatter: formatter).keyboardType(.numberPad)
            Text("Echo: \(number)")
            Text("Observable")
            TextField("int", value: $model.number, formatter: formatter).keyboardType(.numberPad)
            Text("Echo: \(model.number)")
        }
    }
}

struct TextFieldFormatter_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldFormatter()
    }
}

extension View {
    func endEditing() {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to:nil, from:nil, for:nil)
    }
}
3
Erik Peterson

SwiftUIのTextFieldにはいくつかのコンストラクタがあります。それらの1つはFormatterパラメーターを取ります。

https://developer.Apple.com/documentation/swiftui/textfield

import SwiftUI

struct TextFieldFormatter: View {
    @ObservedObject var model: Model = Model.shared

    let formatter: NumberFormatter = {
        let numFormatter = NumberFormatter()
        numFormatter.numberStyle = .none
        return numFormatter
    }()

    var body: some View {
        VStack {
            Text("State").onTapGesture {
                self.endEditing()
            }
            TextField("int", value: $model.number, formatter: formatter).keyboardType(.numberPad)
            Text("Echo: \(model.number)")
            Text("Observable")
            TextField("int", value: $model.number, formatter: formatter).keyboardType(.numberPad)
            Text("Echo: \(model.number)")
        }
    }
}

struct TextFieldFormatter_Previews: PreviewProvider {
    static var previews: some View {
        TextFieldFormatter()
    }
}

また、onTapGestureを使用して画面を無効にしようとしている場合も検討してください。

追加:

   @State var disabled: Bool = false

そして変更:

       Form {
            Text("Disable").onTapGesture {
                //self.endEditing()
                self.disabled = true
            }
            TextField("int", value: $model.number, formatter: formatter).keyboardType(.numberPad)
            Text("Echo: \(model.number)")
            Text("Observable")
            TextField("int", value: $model.number, formatter: formatter).keyboardType(.numberPad)
            Text("Echo: \(model.number)")
        }.disabled($disabled.wrappedValue)

ユーザーが入力しているときにフィードバックを送信する方法はいくつかありますが、UITextViewクラスのカスタムUIViewRepresentableが最も一般的です。

1
CranialDev