【问题标题】:How do I make my own focusable view in SwiftUI using FocusState?如何使用 FocusState 在 SwiftUI 中制作自己的可聚焦视图?
【发布时间】:2022-09-29 18:08:06
【问题描述】:

所以我想将自定义控件实现为UIViewRepresentable,它使用@FocusState 绑定正确处理焦点。

所以我希望能够像这样管理焦点:

struct MyControl: UIViewRepresentable { ... }


struct Container: View {

    @FocusState var hasFocus: Bool = false

    var body: some View {
        VStack {
            MyControl()
                .focused($hasFocus)

            Button(\"Focus my control\") {
                hasFocus = true
            }
        }
    }
}

我必须在MyControl 中实现什么才能让它正确响应焦点状态?是否有必须实施的协议或其他东西?

  • 当我们使用 Textfeld 或使用用户输入工作的控制器时,焦点最有意义,在您的问题中,您的自定义视图没有焦点没有意义。除非我理解错了,否则你在看什么?
  • 我的自定义视图是一个自定义控件,可以响应用户输入。这将包装一个 UITextField 所以我想将焦点系统从 UIKit 集成到 SwiftUI 焦点处理。

标签: ios swiftui combine


【解决方案1】:

免责声明:该解决方案不适合完全自定义控件。对于这些情况,您可以尝试将 FocusState 作为绑定传递:let isFieldInFocus: FocusState<Int?>.Binding

就我而言,我已经包装了 UITextView。为了设置焦点,我只使用了.focused($isFieldInFocus)。 一些信息可以通过属性包装器(@Environment(\.))获取,但是这个技巧对焦点不起作用。

struct ContentView: View {
    @FocusState var isFieldInFocus: Bool
    @State var text = "Test message"
    @State var isDisabled = false
    
    var body: some View {
        VStack {
            Text("Focus for UITextView")
                .font(.headline)

            AppTextView(text: $text)
                .focused($isFieldInFocus)
                .disabled(isDisabled)
                .frame(height: 200)
            
            HStack {
                Button("Focus") {
                    isFieldInFocus = true
                }
                .buttonStyle(.borderedProminent)
                Button("Enable/Disable") {
                    isDisabled.toggle()
                }
                .buttonStyle(.borderedProminent)
            }
        }
        .padding()
        .background(.gray)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct AppTextView: UIViewRepresentable {
    @Binding var text: String
    @Environment(\.isEnabled) var isEnabled: Bool
    @Environment(\.isFocused) var isFocused: Bool // doesn't work
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.font = UIFont.preferredFont(forTextStyle: .body)
        textView.delegate = context.coordinator
        
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = text
        print("isEnabled", isEnabled, "isFocused", isFocused)
    }
    
    class Coordinator : NSObject, UITextViewDelegate {
        private var parent: AppTextView
        
        init(_ textView: AppTextView) {
            self.parent = textView
        }
        
        func textViewDidChange(_ textView: UITextView) {
            parent.text = textView.text
        }
    }
}

【讨论】:

    猜你喜欢
    • 2021-12-09
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    相关资源
    最近更新 更多