我对这个问题有不同的回答,但我很困惑。我对Swift比较陌生。我目前正在为学校的高级项目工作。希望有人回答这个问题,但也会详细介绍。当前行为仅执行0-9。我不能让它做10号。
struct ContentView: View {
// Private vars for tracking
@State private var hoursSlept = 0;
// *** What happens if the user enters something other than an integer/double?
@State private var depressedMood = ""
@State private var elevatedMood = ""
@State private var anxietyMood = ""
@State private var irritabilityMood = ""
@State private var maxLength = 1;
// Var for button
@State private var enterButtonPress = false
var body: some View {
VStack {
NavigationView {
Form {
// Hours slept last night (0-24)
Stepper(value: $hoursSlept, in: 0...24, label: {
Text("Hours slept last night: \(self.hoursSlept)")
})
TextField("Depression 0-10", text: $depressedMood)
.keyboardType(.numberPad)
.onReceive(Just(depressedMood)) {
guard !$0.isEmpty else {
self.depressedMood = ""
return
}
if let value = Int($0.filter(\.isWholeNumber).prefix(maxLength)) {
self.depressedMood = String(value)
}
}
TextField("Elevation 0-10", text: $elevatedMood)
.keyboardType(.numberPad)
.onReceive(Just(elevatedMood)) {
guard !$0.isEmpty else {
self.elevatedMood = ""
return
}
if let value = Int($0.filter(\.isWholeNumber).prefix(maxLength)) {
self.elevatedMood = String(value)
}
}
TextField("Anxiety 0-10", text: $anxietyMood)
.keyboardType(.numberPad)
.onReceive(Just(anxietyMood)) {
guard !$0.isEmpty else {
self.anxietyMood = ""
return
}
if let value = Int($0.filter(\.isWholeNumber).prefix(maxLength)) {
self.anxietyMood = String(value)
}
}
TextField("Irritability 0-10", text: $irritabilityMood)
.keyboardType(.numberPad)
.onReceive(Just(irritabilityMood)) {
guard !$0.isEmpty else {
self.irritabilityMood = ""
return
}
if let value = Int($0.filter(\.isWholeNumber).prefix(maxLength)) {
self.irritabilityMood = String(value)
}
}
答案 0 :(得分:0)
这是一个可能的解决方案-使用~=
并检查该值是否在范围内:
struct ContentView: View {
@State private var depressedMood = ""
var body: some View {
TextField("Depression 0-10", text: $depressedMood)
.keyboardType(.numberPad)
.onReceive(Just(depressedMood)) {
guard let value = Int($0), 0...10 ~= value else {
self.depressedMood = ""
return
}
self.depressedMood = String(value)
}
}
}
答案 1 :(得分:0)
您应该尝试使用自定义TextField,以便可以管理逻辑。然后,您可以将其绑定到所需的任何文本字段。
class TextBindingManager: ObservableObject {
@Published var text = "" {
didSet {
guard let newValue = Int(text) else {
text = oldValue
return
}
if( !(newValue >= range.lowerBound) || !(newValue <= range.upperBound)) {
text = oldValue
}
}
}
let range: Range<Int>
init(limit: Range<Int> = 0..<10){
range = limit
}
}
然后可以通过绑定将其放置在您喜欢的任何地方
struct MyView: View {
@ObservedObject var textBindingManager = TextBindingManager()
var body: some View {
TextField("", text: $textBindingManager.text, onEditingChanged: { _ in }, onCommit: {})
}
}
答案 2 :(得分:0)
考虑到您已将字段的maxLength设置为1,这绝对是预期的行为。最简单的方法是在字段中添加出价管理器,检查输入的文本是否在您的范围内,否则将其值设置为最后一个值:
import SwiftUI
struct ContentView: View {
@ObservedObject private var bindingManager = TextBindingManager(string: "")
@State private var depressedMood = ""
var body: some View {
TextField("Depression 0-10", text: $bindingManager.string)
.onChange(of: bindingManager.string) { newValue in
// this allows the user to clear the field
if bindingManager.string.isEmpty { return }
guard let newValue = Int(bindingManager.string), 0...10 ~= newValue else {
// this would allow the user to replace the current value
// you can comment out this if you want to force the user to clear the contents using the delete backwards key before entering new value
if let digit = bindingManager.string.last?.wholeNumberValue {
bindingManager.string = String(digit)
depressedMood = bindingManager.string
return
}
// this would leave the field unchanged if an invalud value is entered
bindingManager.string = depressedMood
depressedMood = bindingManager.string
return
}
bindingManager.string = String(newValue)
depressedMood = bindingManager.string
}
.keyboardType(.numberPad)
.padding()
}
}
class TextBindingManager: ObservableObject {
@Published var string: String = ""
init(string: String) { self.string = string }
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
答案 3 :(得分:0)
您可以使用类似以下的简单内容:
struct ContentView: View {
@State var depressedMood = ""
var body: some View {
VStack {
TextField("0-10", text: $depressedMood)
.keyboardType(.numberPad)
.onChange(of: depressedMood) {
let txt = $0.filter("0123456789".contains)
if let num = Int(txt), num <= 10, txt.count <= 2 {
depressedMood = txt
} else {
depressedMood = String(txt.dropLast())
}
}
}
}
}