我写了propertyWrapperMaxCount
来限制. 但是,虽然view 显示 trimmed ,但显示 full 。String
TextField
Text
String
TextField
String
我可以通过 below 实现预期的行为ViewModifier
,但这对我来说似乎不是一个好习惯,我想通过@propertyWrapper
.
TextField("Type here...", text: $text)
.onChange(of: text) { newText in
// Check if newText has more characters than maxCount, if so trim it.
guard maxCount < newText.count else { text = newText; return }
text = String(newText.prefix(maxCount))
}
MaxCount.swift
@propertyWrapper struct MaxCount<T: RangeReplaceableCollection>: DynamicProperty {
// MARK: Properties
private var count: Int = 0
@State private var value: T = .init()
var wrappedValue: T {
get { value }
nonmutating set {
value = limitValue(newValue, count: count)
}
}
var projectedValue: Binding<T> {
Binding(
get: { value },
set: { wrappedValue = $0 }
)
}
// MARK: Initilizations
init(wrappedValue: T, _ count: Int) {
self.count = count
self._value = State(wrappedValue: limitValue(wrappedValue, count: count))
}
// MARK: Functions
private func limitValue(_ value: T, count: Int) -> T {
guard value.count > count else { return value }
let lastIndex = value.index(value.startIndex, offsetBy: count - 1)
let firstIndex = value.startIndex
return T(value[firstIndex...lastIndex])
}
}
ContentView.swift
struct ContentView: View {
@MaxCount(5) private var text = "This is a test text"
var body: some View {
VStack {
Text(text)
TextField("Type here...", text: $text)
}
}
}