我已将我们的生产代码分解为基本要素。
我们为 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()
})
}
}
以下是重现该行为的步骤:
- 您需要激活第一个文本字段。
- 按显示表对话框
- 在新显示的视图中激活文本字段
- 按关闭按钮关闭工作表
- 尝试单击显示表按钮->单击的位置现在似乎有偏移
我们已经尝试了很多方法来解决问题,但还没有找到好的解决方案或实际原因。有谁知道出了什么问题?
更新:使用简单的 SwiftUITextField 时也会出现此问题。