UIViewRepresentable for UITextField在SwiftUI中生成中断的UI行为

UIViewRepresentable for UITextField在SwiftUI中生成中断的UI行为,swiftui,uikit,uitextfield,uiviewrepresentable,Swiftui,Uikit,Uitextfield,Uiviewrepresentable,我已经把我们的生产代码分解到了最基本的部分 我们为UITextField编写了一个UIViewRepresentable。为了使textfield成为第一个响应者,我们将IsEditing定义为一个可绑定的值。我们将此值传递给协调器,并在UITextFieldDelegate的DidBeginEdit和DidEndEdit中相应地更新它。基本上一切都按预期工作,但一旦您在该视图上方显示一个视图,该视图同时声明第一响应者并再次导航回,下面的UI似乎就坏了。乍一看,一切都是正确的,但如果您在视图调试

我已经把我们的生产代码分解到了最基本的部分

我们为UITextField编写了一个UIViewRepresentable。为了使textfield成为第一个响应者,我们将IsEditing定义为一个可绑定的值。我们将此值传递给协调器,并在UITextFieldDelegate的DidBeginEdit和DidEndEdit中相应地更新它。基本上一切都按预期工作,但一旦您在该视图上方显示一个视图,该视图同时声明第一响应者并再次导航回,下面的UI似乎就坏了。乍一看,一切都是正确的,但如果您在视图调试器中仔细查看,恐惧就会变得显而易见。控件似乎在可视平面上正确定位,但框架在发动机罩下略微偏移

这是UIViewRepresentable的代码:

import SwiftUI

struct UITextFieldRepresentable: UIViewRepresentable {
    @Binding var isEditing: Bool

    init(isEditing: Binding<Bool>) {
        self._isEditing = isEditing
    }

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        textField.delegate = context.coordinator
        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        if isEditing && !uiView.isFirstResponder {
            uiView.becomeFirstResponder()
        } else if !isEditing && uiView.isFirstResponder {
            uiView.resignFirstResponder()
        }
    }

    func makeCoordinator() -> Coordinator {
        return Coordinator(isEditing: $isEditing)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        @Binding var isEditing: Bool

        init(isEditing: Binding<Bool>) {
            self._isEditing = isEditing
        }

        func textFieldDidBeginEditing(_ textField: UITextField) {
            if !isEditing {
               self.isEditing = true
            }
        }

        func textFieldDidEndEditing(_ textField: UITextField) {
            if isEditing {
               self.isEditing = false
            }
        }
    }
}
以下是重现该行为的步骤:

  • 您需要激活第一个文本字段
  • 按“显示图纸”对话框
  • 在新显示的视图中激活文本字段
  • 按“关闭”按钮关闭工作表
  • 尝试单击“显示图纸”按钮->单击的位置现在似乎有偏移
  • 我们已经尝试了很多方法来解决这个问题, 但尚未找到好的解决办法或实际原因。 有人知道出了什么问题吗

    更新
    使用简单的SwiftUITextField时也会出现此问题。

    这是否回答了您的问题?看起来正常情况下也会出现此问题TextField@Asperi不,这不能解决问题。@davidev没错。这可能会有帮助。这回答了你的问题吗?看起来这个问题在正常情况下也会出现TextField@Asperi不,这不能解决问题。@davidev没错。这可能会有所帮助。
    struct ContentView: View {
        var body: some View {
            TestView()
        }
    }
    
    class ViewModel: ObservableObject {
        @Published var isEditing1: Bool = false
    }
    
    struct TestView: View {
        @StateObject var viewModel = ViewModel()
    
        @Environment(\.presentationMode) var presentationMode
    
        @State var showSheet = false
    
        var body: some View {
            ScrollView {
                VStack {
                    Button("dismiss") {
                        presentationMode.wrappedValue.dismiss()
                    }
                    UITextFieldRepresentable(isEditing: $viewModel.isEditing1)
                        .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.blue, style: StrokeStyle()))
                    Button("TestButton") {
    
                    }
                    .background(Color.red)
                    Button("TestButton") {
    
                    }
                    .background(Color.yellow)
                    Button("ShowSheet") {
                        showSheet = true
                    }
                    .background(Color.green)
                }
            }.sheet(isPresented: $showSheet, content: {
                TestView()
            })
        }
    }