表格货币输入
Form Currency Input
我正在寻求有关通过表单输入货币的帮助。我想要:
- 允许输入单个小数/逗号货币分隔符
- 限制输入小数点后 2 位数字
- 允许编辑值
- 限制输入的最大数字
6 年前在 Limiting user input to a valid decimal number in Swift 上也有人问过类似的问题,但所有答案似乎都在使用 viewDidLoad。我认为这在表单条目中是不可行的。如果可行,请告诉我怎么做。谢谢
表格{
...
// Enter entry amount
Section {
TextField("Enter Amount > " + curr, text: $moneyS)
.keyboardType(.decimalPad)
}
// select entry save or cancel
Section {
Button(action: {
self.showingAlert.toggle()
...
按照思路来实现,没有涵盖你的所有观点,但我认为自己进行就足够了:
class Test2Model: ObservableObject {
@Published var currLimit: Double = 4.0
@Published var digitLimit: Int = 2
func getCurr(str: String) -> String{
guard let currInserted = Double(str)
else {
return String(currLimit)
}
if currInserted <= currLimit {
return String(currLimit)
}
return str
}
}
struct Test2View: View {
@ObservedObject private var test2Model = Test2Model()
@State private var moneyS: String = ""
var body: some View {
Form {
// Enter entry amount
Section {
TextField("Enter Amount > " + String(test2Model.currLimit), text: $moneyS)
.keyboardType(.decimalPad)
.onChange(of: moneyS, perform: { value in
guard let decimals = moneyS.components(separatedBy:".").last else {return}
if decimals.count > test2Model.digitLimit {
moneyS.removeLast()
}
})
}
// select entry save or cancel
Section {
Button(action: {
moneyS = test2Model.getCurr(str: moneyS)
}, label: {
Text("Check")
})
}
}
}
}
struct Test2View_Previews: PreviewProvider {
static var previews: some View {
Test2View()
}
}
你可以尝试这样的事情:
struct ContentView: View {
let maxDigits = 6
let maxDecimals = 2
let allowedCharacters = CharacterSet.decimalDigits.union(CharacterSet(charactersIn: NumberFormatter().decimalSeparator))
@State var money: Double?
@State var moneyText = ""
var body: some View {
VStack (spacing: 30) {
Spacer()
TextField("enter a number", text: $moneyText)
.padding(.horizontal, 20)
.keyboardType(.decimalPad)
.onChange(of: moneyText) {
// to prevent pasting non-valid text
let txt = [=10=].filter { ".0123456789".contains([=10=]) }
if allowed(txt) {
money = Double(txt)
moneyText = txt
} else {
moneyText = String(txt.dropLast())
}
}
Text("Money value is: \(money ?? 0)")
Spacer()
}
}
func allowed(_ txt: String) -> Bool {
let str = txt.trimmingCharacters(in: .whitespacesAndNewlines)
switch str.components(separatedBy: ".").count - 1 {
case 0:
if str.count > maxDigits {
return false
}
return allowedCharacters.isSuperset(of: CharacterSet(charactersIn: str))
case 1:
if str.starts(with: ".") && (str.count - 1) > maxDecimals {
return false
}
let parts = str.split(separator: ".")
if parts.count == 2 && (parts[1].count > maxDecimals) || (str.count - 1) > maxDigits {
return false
}
return allowedCharacters.isSuperset(of: CharacterSet(charactersIn: str))
default:
return false
}
}
}
我正在寻求有关通过表单输入货币的帮助。我想要:
- 允许输入单个小数/逗号货币分隔符
- 限制输入小数点后 2 位数字
- 允许编辑值
- 限制输入的最大数字
6 年前在 Limiting user input to a valid decimal number in Swift 上也有人问过类似的问题,但所有答案似乎都在使用 viewDidLoad。我认为这在表单条目中是不可行的。如果可行,请告诉我怎么做。谢谢
表格{
...
// Enter entry amount
Section {
TextField("Enter Amount > " + curr, text: $moneyS)
.keyboardType(.decimalPad)
}
// select entry save or cancel
Section {
Button(action: {
self.showingAlert.toggle()
...
按照思路来实现,没有涵盖你的所有观点,但我认为自己进行就足够了:
class Test2Model: ObservableObject {
@Published var currLimit: Double = 4.0
@Published var digitLimit: Int = 2
func getCurr(str: String) -> String{
guard let currInserted = Double(str)
else {
return String(currLimit)
}
if currInserted <= currLimit {
return String(currLimit)
}
return str
}
}
struct Test2View: View {
@ObservedObject private var test2Model = Test2Model()
@State private var moneyS: String = ""
var body: some View {
Form {
// Enter entry amount
Section {
TextField("Enter Amount > " + String(test2Model.currLimit), text: $moneyS)
.keyboardType(.decimalPad)
.onChange(of: moneyS, perform: { value in
guard let decimals = moneyS.components(separatedBy:".").last else {return}
if decimals.count > test2Model.digitLimit {
moneyS.removeLast()
}
})
}
// select entry save or cancel
Section {
Button(action: {
moneyS = test2Model.getCurr(str: moneyS)
}, label: {
Text("Check")
})
}
}
}
}
struct Test2View_Previews: PreviewProvider {
static var previews: some View {
Test2View()
}
}
你可以尝试这样的事情:
struct ContentView: View {
let maxDigits = 6
let maxDecimals = 2
let allowedCharacters = CharacterSet.decimalDigits.union(CharacterSet(charactersIn: NumberFormatter().decimalSeparator))
@State var money: Double?
@State var moneyText = ""
var body: some View {
VStack (spacing: 30) {
Spacer()
TextField("enter a number", text: $moneyText)
.padding(.horizontal, 20)
.keyboardType(.decimalPad)
.onChange(of: moneyText) {
// to prevent pasting non-valid text
let txt = [=10=].filter { ".0123456789".contains([=10=]) }
if allowed(txt) {
money = Double(txt)
moneyText = txt
} else {
moneyText = String(txt.dropLast())
}
}
Text("Money value is: \(money ?? 0)")
Spacer()
}
}
func allowed(_ txt: String) -> Bool {
let str = txt.trimmingCharacters(in: .whitespacesAndNewlines)
switch str.components(separatedBy: ".").count - 1 {
case 0:
if str.count > maxDigits {
return false
}
return allowedCharacters.isSuperset(of: CharacterSet(charactersIn: str))
case 1:
if str.starts(with: ".") && (str.count - 1) > maxDecimals {
return false
}
let parts = str.split(separator: ".")
if parts.count == 2 && (parts[1].count > maxDecimals) || (str.count - 1) > maxDigits {
return false
}
return allowedCharacters.isSuperset(of: CharacterSet(charactersIn: str))
default:
return false
}
}
}