[英]Detect `FocusState` changes in reusable TextField composite views
我想創建一個嵌入TextField
的可重用view
和一個可視指示器(下划線Rectangle
)視圖,當TextField
正在編輯(即有焦點)時會改變顏色。
在一個示例容器視圖中,我可能有幾個這樣的可重用視圖,並且我正在使用FocusState
模式,如下所示:
private enum FocusedField {
case first
case second
case third
}
@FocusState private var focusedField: FocusedField?
MyCustomTextField(...)
.focused($focusedField, equals: .second)
一般來說,這是可行的。 焦點將轉移到自定義文本字段,即使它位於具有TextField
和Rectangle(...)
的容器視圖內。 (不太確定我是否理解這是如何工作的,tbh)
但是,我不知道如何根據關聯的TextField
是否具有焦點來一般地讓Rectangle
更改顏色。
矩形只是:
Rectangle()
.fill(isFocused ? Color.blue : Color.gray)
.frame(maxWidth: .infinity, minHeight: 2, maxHeight: 2)
.padding(.horizontal)
任何指導表示贊賞。
您可以將FocusState
和值傳遞給您的CustomTextField
視圖。
這是演示代碼。
struct MyCustomTextField<Value: Hashable>: View {
@Binding var text: String
var focusedField: FocusState<Value?>.Binding
var value: Value
var body: some View {
VStack {
TextField("Placeholder", text: $text)
.focused(focusedField, equals: value)
Rectangle()
.fill(focusedField.wrappedValue == value ? Color.blue : Color.gray)
.frame(maxWidth: .infinity, minHeight: 2, maxHeight: 2)
.padding(.horizontal)
}
}
}
struct ContentView: View {
@State var firstTextField: String = ""
@State var secondTextField: String = ""
@State var thirdTextField: String = ""
@FocusState private var focusedField: FocusedField?
var body: some View {
VStack {
MyCustomTextField(text: $firstTextField, focusedField: $focusedField, value: .first)
MyCustomTextField(text: $secondTextField, focusedField: $focusedField, value: .second)
MyCustomTextField(text: $thirdTextField, focusedField: $focusedField, value: .third)
Button("Change") {
switch focusedField {
case .first:
focusedField = .second
case .second:
focusedField = .third
default:
focusedField = .first
}
}
}
}
}
只使用內部自己的FocusState
,它與外部不沖突
struct MyCustomTextField: View {
@Binding var text: String
@FocusState var isFocused // << internal
var body: some View {
TextField("", text: $text)
.focused($isFocused) // << get state
.padding()
.background(
Rectangle()
.fill(isFocused ? Color.blue : Color.gray) // !!
.frame(maxWidth: .infinity, minHeight: 2, maxHeight: 2)
.padding(.horizontal)
, alignment: .bottom)
}
}
使用 Xcode 13.4 / iOS 15.5 測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.