表单中的SwiftUI Picker在键盘显示时立即弹出



我在NavigationView中有一个表单,它显示了未知数量的用于捕获客户输入的字段。一些字段是纯TextFields,其他字段是具有多个选择的Pickers。如果Picker在表单中的位置足够低,以至于在TextField聚焦时被键盘覆盖,那么在键盘向上的情况下轻击Picker会阻止成功过渡到Picker的自动生成的详细视图。detail视图被推送并立即弹出,这阻止了选择。

在这个网站上还有很多关于自动弹出NavigationView/NavigationLinks的问题,但我已经在一个简单的ContentView示例应用程序中复制了这个问题,并确定了一些关键的发现,使我相信这可能是一个bug:

  1. 在选择器之前的表单中的项目数量决定是否发生这种情况,并且根据屏幕大小而不同。对于iPhone 13, 9+ TextFields在Picker之前导致这个发生;对于iPhone 13 Pro Max,在Picker导致这种情况发生之前,12+ TextFields。
  2. 对于相同数量的总项目在窗体中,移动的选择器更高的窗体防止这种情况发生。如果选择了任何TextField,则选择器不会被键盘覆盖,则不会发生此问题。
  3. 如果在点击选择器时键盘不可见,则无论窗体中有多少项,问题都不会发生。
class Model: ObservableObject {
@Published var fields: [Field] = [
Field(id: "1"), Field(id: "2"), Field(id: "3"), Field(id: "4"), Field(id: "5"), Field(id: "6"),
Field(id: "7"), Field(id: "8"), Field(id: "9"), Field(id: "10"), Field(id: "11"), Field(id: "12"),
Field(id: "13", type: .Picker(options: ["A", "B", "C"])),
]
}
struct Field: Identifiable {
enum FieldType {
case Text
case Picker(options: [String])
}

let id: String
let type: FieldType
var value: String

init(id: String, type: FieldType = .Text) {
self.id = id
self.type = type
self.value = ""
}
}
struct ContentView: View {

@StateObject var model = Model()

var body: some View {
NavigationView {
Form {
Section {
ForEach($model.fields) { $field in
switch field.type {
case .Text:
TextField(field.id, text: $field.value)
case .Picker(let options):
Picker("Picker", selection: $field.value) {
ForEach(options, id: .self) {
Text($0)
}
}
}
}
}
}
}
}
}

我可以确认这个问题我还可以补充一句:当键盘隐藏时,程序激活的NavigationLink会弹出。我觉得这是个bug。

基于OPs代码的示例,带有额外的可编程Navlink:

struct ContentView: View {

@StateObject var model = Model()
@State private var selected = false

var body: some View {
NavigationView {
Form {
Section {
Button("activate hidden link") { selected = true }
ForEach($model.fields) { $field in
switch field.type {
case .Text:
TextField(field.id, text: $field.value)
case .Picker(let options):
Picker("Picker", selection: $field.value) {
ForEach(options, id: .self) {
Text($0)
}
}
}
}
NavigationLink("Test Link", isActive: $selected) {
Text("Destination")
}
}
}
}
}
}

最新更新