1

我已将我们的生产代码分解为基本要素。

我们为 UITextField 编写了一个 UIViewRepresentable。为了使 textfeild 成为第一响应者,我们将 IsEditing 定义为可绑定值。我们将此值传递给协调器,并在 UITextFieldDelegate 的 didBeginEditing 和 didEndEditing 中相应地更新它。基本上一切都按预期工作,但是一旦您在此视图上方显示一个视图,该视图也声称 FirstResponder 并再次导航回来,下面的 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
            }
        }
    }
}

这是产生错误的代码。

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()
        })
    }
}

以下是重现该行为的步骤:

  1. 您需要激活第一个文本字段。
  2. 按显示表对话框
  3. 在新显示的视图中激活文本字段
  4. 按关闭按钮关闭工作表
  5. 尝试单击显示表按钮->单击的位置现在似乎有偏移

破帧

我们已经尝试了很多方法来解决问题,但还没有找到好的解决方案或实际原因。有谁知道出了什么问题?

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

4

0 回答 0