SwiftUI TextField 数字输入
SwiftUI TextField Number Input
我试图让用户输入两个数字,然后显示这些数字并将它们相加。目前,为了更新状态变量,您需要按 return。有没有办法像处理文本一样更新状态?我也将代码作为字符串输入,但无法将其转换为 int,因此无法正确地将数字相加。如果有人知道如何正确转换它,我将不胜感激我能得到的所有帮助。
struct ContentView: View {
@State private var numOne: Int = 0
@State private var numTwo: Int = 0
var body: some View {
NavigationView {
VStack {
Form {
Section {
TextField("Number One", value: $numOne, formatter: NumberFormatter())
.keyboardType(.numberPad)
TextField("Number Two", value: $numTwo, formatter: NumberFormatter())
.keyboardType(.numberPad)
}
NavigationLink(
destination: addedView(numOne: $numOne, numTwo: $numTwo),
label: {
Text("Navigate")
}
)
}
}
}
}
}
struct addedView: View {
@Binding var numOne: Int
@Binding var numTwo: Int
@State private var added: Int = 0
var body: some View {
VStack {
Text("\(numOne)")
Text("\(numTwo)")
}
}
}
这使用 Combine 来确保输入的文本是数字,然后将其更改为 Int 以用于计算。 return 值是一个闭包,您可以使用它来
struct EditableInt : View {
var intString: String = ""
var onChanged: (Int) -> Void
init(_ int: Int?, onChanged: @escaping (Int) -> Void) {
if let int = int,
let formattedInt = Formatter.numberFormatter.string(from: int as NSNumber){
self.intString = formattedInt
} else {
intString = ""
}
self.onChanged = onChanged
}
@State private var editableInt: String = ""
var body: some View {
TextField(" " + intString + " ", text: $editableInt)
.onReceive(Just(editableInt)) { newValue in
let editableInt = newValue.filter { "0123456789".contains([=10=]) }
if editableInt != intString {
if let returnInt = Int(editableInt) {
onChanged(returnInt)
}
}
}
.onAppear { self.editableInt = self.intString }
}
}
以上是可重用的,从另一个视图调用是这样的:
struct OtherView: View {
@State var otherViewInt = 0
var body: some View {
EditableInt(otherViewInt) { newInt in
otherViewInt = newInt
}
}
}
这说明了如何强制 TextField
为整数,以及如何将它们相加得到一个结果。
主要区别在于格式化程序的 numberStyle
是 .decimal
。这意味着您只会得到整数/整数。
结果是 Int
时添加的,因此添加了 个数字 。如果您在它们都是 String
时添加,它们将 连接 在一起。例如。您希望 5 + 10
成为 15
,而不是 510
。
然后您可以将 result
传递给子视图或 NavigationLink
如果您愿意。
struct ContentView: View {
@State private var numOne: Int = 0
@State private var numTwo: Int = 0
private static let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()
private var result: Int {
numOne + numTwo
}
var body: some View {
NavigationView {
VStack {
Form {
Section {
TextField("Number One", value: $numOne, formatter: Self.formatter)
.keyboardType(.numberPad)
TextField("Number Two", value: $numTwo, formatter: Self.formatter)
.keyboardType(.numberPad)
}
Section {
Text("Result: \(result)")
}
}
}
}
}
}
请注意,NumberFormatter
是静态创建的,并且仅创建一次。这是因为创建它们非常昂贵,尤其是两次每个渲染。
我试图让用户输入两个数字,然后显示这些数字并将它们相加。目前,为了更新状态变量,您需要按 return。有没有办法像处理文本一样更新状态?我也将代码作为字符串输入,但无法将其转换为 int,因此无法正确地将数字相加。如果有人知道如何正确转换它,我将不胜感激我能得到的所有帮助。
struct ContentView: View {
@State private var numOne: Int = 0
@State private var numTwo: Int = 0
var body: some View {
NavigationView {
VStack {
Form {
Section {
TextField("Number One", value: $numOne, formatter: NumberFormatter())
.keyboardType(.numberPad)
TextField("Number Two", value: $numTwo, formatter: NumberFormatter())
.keyboardType(.numberPad)
}
NavigationLink(
destination: addedView(numOne: $numOne, numTwo: $numTwo),
label: {
Text("Navigate")
}
)
}
}
}
}
}
struct addedView: View {
@Binding var numOne: Int
@Binding var numTwo: Int
@State private var added: Int = 0
var body: some View {
VStack {
Text("\(numOne)")
Text("\(numTwo)")
}
}
}
这使用 Combine 来确保输入的文本是数字,然后将其更改为 Int 以用于计算。 return 值是一个闭包,您可以使用它来
struct EditableInt : View {
var intString: String = ""
var onChanged: (Int) -> Void
init(_ int: Int?, onChanged: @escaping (Int) -> Void) {
if let int = int,
let formattedInt = Formatter.numberFormatter.string(from: int as NSNumber){
self.intString = formattedInt
} else {
intString = ""
}
self.onChanged = onChanged
}
@State private var editableInt: String = ""
var body: some View {
TextField(" " + intString + " ", text: $editableInt)
.onReceive(Just(editableInt)) { newValue in
let editableInt = newValue.filter { "0123456789".contains([=10=]) }
if editableInt != intString {
if let returnInt = Int(editableInt) {
onChanged(returnInt)
}
}
}
.onAppear { self.editableInt = self.intString }
}
}
以上是可重用的,从另一个视图调用是这样的:
struct OtherView: View {
@State var otherViewInt = 0
var body: some View {
EditableInt(otherViewInt) { newInt in
otherViewInt = newInt
}
}
}
这说明了如何强制 TextField
为整数,以及如何将它们相加得到一个结果。
主要区别在于格式化程序的 numberStyle
是 .decimal
。这意味着您只会得到整数/整数。
结果是 Int
时添加的,因此添加了 个数字 。如果您在它们都是 String
时添加,它们将 连接 在一起。例如。您希望 5 + 10
成为 15
,而不是 510
。
然后您可以将 result
传递给子视图或 NavigationLink
如果您愿意。
struct ContentView: View {
@State private var numOne: Int = 0
@State private var numTwo: Int = 0
private static let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()
private var result: Int {
numOne + numTwo
}
var body: some View {
NavigationView {
VStack {
Form {
Section {
TextField("Number One", value: $numOne, formatter: Self.formatter)
.keyboardType(.numberPad)
TextField("Number Two", value: $numTwo, formatter: Self.formatter)
.keyboardType(.numberPad)
}
Section {
Text("Result: \(result)")
}
}
}
}
}
}
请注意,NumberFormatter
是静态创建的,并且仅创建一次。这是因为创建它们非常昂贵,尤其是两次每个渲染。