当我们想要观察 SwiftUI 文本字段的焦点状态时,环境值 isFocused 似乎不起作用。除了将值传递给 TextFieldStyle 的 init(我们必须为每个 Textfield 执行此操作)之外,还有其他方法可以做到这一点吗?在设备上也不起作用。
当文本字段的焦点状态发生变化时,更改其外观的首选方法是什么?
Example:
SwiftUI TextFieldStyle 定义如下:
struct MyTextFieldStyle: TextFieldStyle {
@Environment(\.isFocused) var isFocused: Bool
func _body(configuration: TextField<_Label>) -> some View {
configuration
.padding()
.overlay(
RoundedRectangle(
cornerRadius: 10.0, style: .continuous
)
.stroke(isFocused ? .green : .gray, lineWidth: 3)
)
.accentColor(Color(uiColor: .white))
}
}
#if DEBUG
private struct TestView: View {
@FocusState private var focusedTextfield: FocusField?
enum FocusField: Hashable {
case textfield1, textfield2
}
var body: some View {
VStack(spacing: 16) {
TextField("hello", text: .constant("Hi"))
.textFieldStyle(MyTextFieldStyle())
.focused($focusedTextfield, equals: .textfield1)
TextField("hello", text: .constant("Hi"))
.textFieldStyle(MyTextFieldStyle())
.focused($focusedTextfield, equals: .textfield2)
}.onAppear {
focusedTextfield = .textfield1
}
}
}
struct MyTextfieldStyle_Previews: PreviewProvider {
static var previews: some View {
ZStack {
TestView()
}
}
}
#endif
// 编辑:基于的工作解决方案https://stackoverflow.com/a/72092987/7828383 https://stackoverflow.com/a/72092987/7828383
struct MyTextFieldStyle: TextFieldStyle {
@FocusState var isFocused: Bool
func _body(configuration: TextField<_Label>) -> some View {
configuration
.padding()
.focused($isFocused)
.overlay(
RoundedRectangle(
cornerRadius: 10.0, style: .continuous
)
.stroke(isFocused ? .green : .gray, lineWidth: 3)
)
.accentColor(Color(uiColor: .white))
}
}
#if DEBUG
private struct TestView: View {
@FocusState private var focusedTextfield: FocusField?
enum FocusField: Hashable {
case textfield1, textfield2
}
var body: some View {
VStack(spacing: 16) {
TextField("hello", text: .constant("Hi"))
.textFieldStyle(MyTextFieldStyle())
.focused($focusedTextfield, equals: .textfield1)
TextField("hello", text: .constant("Hi"))
.textFieldStyle(MyTextFieldStyle())
.focused($focusedTextfield, equals: .textfield2)
}.onAppear {
DispatchQueue.main.async {
focusedTextfield = .textfield1
}
}
}
}
struct MyTextFieldStyle_Previews: PreviewProvider {
static var previews: some View {
ZStack {
TestView()
}
}
}
#endif