SwiftUI 中 FocusState 变化导致键盘弹跳

Gad*_*get 22 ios swift swiftui

我正在 SwiftUI 中为 iOS 制作一个登录界面。用户应该能够通过点击软件键盘上的“下一步”按钮轻松地从用户名文本字段切换到密码文本字段。它运行良好,但由于某种原因在两个文本字段之间切换时键盘总是会弹起一点。编辑:正如这个答案中所建议的,我在 VStack 中添加了一个 Spacer 以使其填充可用空间。文本字段不再弹跳,但不幸的是键盘仍然弹跳。我已经更新了代码和 GIF 以反映我的更改。

问题记录

经过一番谷歌搜索后,这似乎不是一个很常见的问题。这个问题似乎与发生在我身上的事情类似,但遵循答案并将文本字段包装在 ScrollView 或 GeometryReader 中根本没有改变任何东西。这是我的代码:

struct AuthenticationView: View {
  @State var userName: String = ""
  @State var userAuth: String = ""
  
  @FocusState var currentFocus: FocusObject?
  enum FocusObject: Hashable { case name, auth }
  
  var body: some View {
    VStack(spacing: 8) {
      TextField("Username", text: $userName)
        .focused($currentFocus, equals: .name)
        .padding(8).background(Color.lightGray)
        .cornerRadius(8).padding(.bottom, 8)
        .textInputAutocapitalization(.never)
        .onSubmit { currentFocus = .auth }
        .autocorrectionDisabled(true)
        .keyboardType(.asciiCapable)
        .textContentType(.username)
        .submitLabel(.next)
      
      SecureField("Password", text: $userAuth)
        .focused($currentFocus, equals: .auth)
        .padding(8).background(Color.lightGray)
        .cornerRadius(8).padding(.bottom, 16)
        .textInputAutocapitalization(.never)
        .onSubmit { currentFocus = nil }
        .autocorrectionDisabled(true)
        .keyboardType(.asciiCapable)
        .textContentType(.password)
        .submitLabel(.done)
      
      Spacer() // This fixes the text fields
      // But it does not fix the keyboard
    }.padding(32)
  }
}
Run Code Online (Sandbox Code Playgroud)

Cou*_*per 0

您当前的布局显示:

将编辑字段放入 VStack 中。通过将 VStack 置于可用空间的中心来在父视图中布局 VStack 。请注意,VStack 仅使用最小大小。

现在,当键盘出现时,父视图的可用空间,即其高度,将相应减少。

由于 VStack 布局在中心,因此文本字段会上下弹跳。

有几种选择:

确保 VStack 延伸其高度并且文本字段在顶部对齐。例如使用Spacer

    VStack(spacing: 8) {
      TextField("Username", text: $userName)
        ...   
    
      SecureField("Password", text: $userAuth)
        ...
    
      Spacer()
    }.padding(32)
Run Code Online (Sandbox Code Playgroud)

使用滚动视图:

    ScrollView {

        Spacer(minLength: 80) // give some space at the top

        VStack(spacing: 8) {
          TextField("Username", text: $userName)
          ...   
    
         SecureField("Password", text: $userAuth)
         ...
    
        }.padding(32)
    }
Run Code Online (Sandbox Code Playgroud)

它可能看起来不太漂亮,但它应该给您一个想法,在哪里解决这个问题(您可能需要使用 GeometryReader 和可能的 ScrollView 来完善您的布局)。

另一种选择是使用Form. 将你的字段放入其中,这样Form你就可以取得一个良好的开端,看起来相当不错。a 起作用的原因Form是因为它与 a 一起工作Spacer(在顶部对齐字段)和 ScrollView 的原因相同。

不幸的是,当您点击“下一步”时,键盘会暂时消失。到目前为止我还没有解决这个问题的办法。