[英]SwiftUI Focus State API environment variable not working
Environment value isFocused doesn't seem to work when we want to observe focus state of SwiftUI textfield.当我们想要观察 SwiftUI 文本字段的焦点 state 时,环境值 isFocused 似乎不起作用。 Is there any other way to do this, besides passing the value to TextFieldStyle's init (which we would have to do for every Textfield)?
除了将值传递给 TextFieldStyle 的初始化(我们必须为每个文本字段执行此操作)之外,还有其他方法可以做到这一点吗? Doesn't work on device either.
也不适用于设备。
What is the preferred way of changing Textfield's appearance when its focus state changes?当其焦点 state 发生变化时,更改 Textfield 外观的首选方法是什么?
Example:例子:
SwiftUI TextFieldStyle defined as follows: 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
// EDIT: Working solution based on 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
You have met a couple of different issues:您遇到了几个不同的问题:
@FocusState
var.@FocusState
var。 I didn't get the environment var working, but this does.asyncAfter
asyncAfter
等待一段时间struct MyTextField: View {
@FocusState private var isFocused: Bool
let title: String
@Binding var text: String
init(_ title: String, text: Binding<String>) {
self.title = title
self._text = text
}
var body: some View {
TextField(title, text: $text)
.focused($isFocused) // important !
.padding()
.overlay(
RoundedRectangle(
cornerRadius: 10.0, style: .continuous
)
.stroke(isFocused ? .green : .gray, lineWidth: 3)
)
.accentColor(Color(uiColor: .red))
}
}
struct ContentView: View {
@FocusState private var focusedTextfield: FocusField?
enum FocusField: Hashable {
case textfield1, textfield2
}
@State private var input1 = "Hi"
@State private var input2 = "Hi2"
var body: some View {
VStack(spacing: 16) {
MyTextField("hello", text: $input1)
.focused($focusedTextfield, equals: .textfield1)
MyTextField("hello", text: $input2)
.focused($focusedTextfield, equals: .textfield2)
// test for changing focus
Button("Field 1") { focusedTextfield = .textfield1}
Button("Field 2") { focusedTextfield = .textfield2}
}
.padding()
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
focusedTextfield = .textfield1
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.