Swift 和 SwiftUI 从 TextField 字符串绑定到模型的已发布可选整数 属性
Swift and SwiftUI binding from TextField string to model's published, optional Integer property
我是 Swift 和 SwiftUI 的新手,我有一个带有 @Published intValue 可选的模型和一个带有 TextField 的视图,其中 text/string 属性 是双向绑定到模型的 intValue 的。需要确保将作为字符串的有效文本输入转换为模型的有效整数。在 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)
}
}
SwiftUI 的 TextField 有几个构造函数。其中之一采用 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)
可以通过几种不同的方式在用户键入时提供反馈,但 UIViewRepresentable
class 中的自定义 UITextView
似乎是最常见的。
您可以创建自定义 Binding
以传递给 TextField
。
这是构建 Binding<String>
的方法(TextField
需要的):
var string = ""
let myBinding = Binding(get: { string }) {
string = [=10=]
}
Binding
构造函数的第一个参数是 getter。此闭包应该 return 所需类型的值。
第二个参数是 setter。它是一个接受新值并对其进行处理的闭包(通常设置另一个值)。
所以,如果你想创建一个 Binding<String>
来传递给 gets/sets appModel.intValue
的 TextField
,你可以创建一个 Binding<String>
和像这样将它传递到 TextField
中:
TextField("", text: .init(
get: { self.appModel.intValue.map(String.init) ?? "" },
set: { self.appModel.intValue = Int([=11=]) }
))
.keyboardType(.numberPad)
我是 Swift 和 SwiftUI 的新手,我有一个带有 @Published intValue 可选的模型和一个带有 TextField 的视图,其中 text/string 属性 是双向绑定到模型的 intValue 的。需要确保将作为字符串的有效文本输入转换为模型的有效整数。在 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)
}
}
SwiftUI 的 TextField 有几个构造函数。其中之一采用 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)
可以通过几种不同的方式在用户键入时提供反馈,但 UIViewRepresentable
class 中的自定义 UITextView
似乎是最常见的。
您可以创建自定义 Binding
以传递给 TextField
。
这是构建 Binding<String>
的方法(TextField
需要的):
var string = ""
let myBinding = Binding(get: { string }) {
string = [=10=]
}
Binding
构造函数的第一个参数是 getter。此闭包应该 return 所需类型的值。
第二个参数是 setter。它是一个接受新值并对其进行处理的闭包(通常设置另一个值)。
所以,如果你想创建一个 Binding<String>
来传递给 gets/sets appModel.intValue
的 TextField
,你可以创建一个 Binding<String>
和像这样将它传递到 TextField
中:
TextField("", text: .init(
get: { self.appModel.intValue.map(String.init) ?? "" },
set: { self.appModel.intValue = Int([=11=]) }
))
.keyboardType(.numberPad)