实现思路
- 自定义样式:
- 文本框边框样式:使用
TextField
和TextEditor
的overlay
修饰符来添加自定义边框。可以通过RoundedRectangle
绘制边框,并设置其颜色、线宽等属性。
- 文本颜色:直接使用
foregroundColor
修饰符来改变文本颜色。
- 占位文本颜色:对于
TextField
,可以通过attributedPlaceholder
来设置占位文本的颜色等属性。对于TextEditor
,需要自定义一个类似占位文本的功能,在文本为空时显示特定文本,并设置其颜色。
- 优化交互体验:
- TextField焦点与键盘类型:使用
@FocusState
来检测TextField
是否获得焦点,当获得焦点时,通过keyboardType
修饰符设置特定的键盘类型,如UIKeyboardType.decimalPad
用于金额输入。
- TextEditor最大输入长度:使用
@State
来存储输入的文本,并在onChange
事件中检测文本长度,当达到最大长度时,给出提示并禁止继续输入。可以通过设置TextEditor
的isEditable
属性来禁止输入。
关键代码示例
import SwiftUI
struct CustomTextField: View {
@FocusState private var isFocused: Bool
@Binding var text: String
let placeholder: String
let keyboardType: UIKeyboardType
let maxLength: Int?
var body: some View {
VStack {
TextField(placeholder, text: $text)
.focused($isFocused)
.keyboardType(keyboardType)
.foregroundColor(.black)
.padding()
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(isFocused ? Color.blue : Color.gray, lineWidth: 1)
)
.attributedPlaceholder(
NSAttributedString(string: placeholder, attributes: [NSAttributedString.Key.foregroundColor: Color.gray])
)
.onChange(of: text) { newValue in
if let maxLength = maxLength, newValue.count > maxLength {
text = String(newValue.prefix(maxLength))
}
}
}
}
}
struct CustomTextEditor: View {
@State private var text = ""
let placeholder: String
let maxLength: Int
var body: some View {
VStack {
TextEditor(text: $text)
.foregroundColor(.black)
.padding()
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.gray, lineWidth: 1)
)
.onChange(of: text) { newValue in
if newValue.count > maxLength {
text = String(newValue.prefix(maxLength))
// 给出友好提示,这里简单使用打印示例
print("已达到最大输入长度")
}
}
if text.isEmpty {
Text(placeholder)
.foregroundColor(.gray)
.padding(.horizontal, 16)
}
}
}
}
struct ContentView: View {
@State private var amountText = ""
@State private var editorText = ""
var body: some View {
VStack {
CustomTextField(text: $amountText, placeholder: "请输入金额", keyboardType:.decimalPad, maxLength: 10)
CustomTextEditor(placeholder: "请输入内容", maxLength: 200)
}
.padding()
}
}