在 Xcode 11.6 / iOS 13.6 中使用以下代码在 SwiftUI 中遇到一个奇怪的错误。
它将渲染两个带有白色边框的文本字段(如果您不使用暗模式,您可以更改为黑色边框)。错误是点击手势识别器的点击区域与 SecureField 的点击区域不同。因此,您可以点击字段的边缘,虽然识别器会触发,但实际的文本字段不会成为第一响应者。
为了说明这一点,我将两个 UITextField(SwiftUI 在后台使用)的背景颜色设置为绿色。要使给定的 UITextField “成为第一响应者”,您必须在此绿色区域内点击,否则您无法在该字段中输入内容。
问题是因为我们的应用程序是跨平台的,即它将运行在 AppKit 或 UIKit 上,我们不想使用任何基于 UIKit 的方法来处理 UI 的工作方式。我们需要知道用户当前正在编辑哪个字段,以便我们可以将该字段的边框颜色设置为绿色(根据我们 UIX 团队的设计要求)。因此,由于我们无法设置委托来监听普通的 UITextField 委托方法,因此我们决定使用轻击手势识别器来确定用户何时编辑给定字段。
然而,现在我们遇到了这个问题,即填充区域包含在我们在 SwiftUI 中添加的 tapGestureRecognizer 中,但底层文本字段本身不会收到这样的手势,除非它位于填充内的较小区域中。
什么是可以纯粹在 SwiftUI 中完成的解决方案?
import PlaygroundSupport
import SwiftUI
import UIKit
public extension View {
var any: AnyView { AnyView(self) }
}
struct Value: Identifiable {
typealias ID = Int
let id: ID
var text: String = ""
}
struct MyView: View {
@State var fields: [Value] = [Value(id: 0), Value(id: 1)]
init() {
UITextField.appearance().backgroundColor = .green
}
var body: some View {
ForEach(fields) { field in
SecureField(
" ",
text: self.$fields[field.id].text,
onCommit: {
print("committed")
})
.onTapGesture {
print("tapped")
}
.padding(12)
.overlay(
RoundedRectangle(
cornerRadius: 5
).stroke(
Color.white,
lineWidth: 2
)
)
}
}
}