簡體   English   中英

檢測可重用 TextField 復合視圖中的“FocusState”變化

[英]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)

一般來說,這是可行的。 焦點將轉移到自定義文本字段,即使它位於具有TextFieldRectangle(...)的容器視圖內。 (不太確定我是否理解這是如何工作的,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 測試

GitHub 上的測試模塊

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM