【问题标题】:SwiftUI not dismissing keyboard correctly after navigating awaySwiftUI 在离开后没有正确关闭键盘
【发布时间】:2023-01-24 02:03:43
【问题描述】:

如果在我上次离开时​​显示键盘,则在导航堆栈中上升一个级别时,我在使用 SwiftUI 时遇到问题。

  1. 在第一个屏幕中,聚焦文本字段并显示键盘
  2. 触发导航链接以在导航堆栈中显示第二个视图
  3. 点击返回返回第一个视图

    预期:键盘应该仍然显示或关闭,屏幕上的所有控件都应该按照编程进行响应

    观察到:键盘未显示,但屏幕的下半部分没有响应,就好像键盘仍然在那里阻止点击输入一样

    具体在下面的示例代码中触发它:

    1. 关注搜索字段以显示键盘
    2. 点击任何链接,例如“第 0 行” 3. 点击“返回”

      观察到:“safeAreaInset bottom”视图移动到屏幕中间。下面的区域没有响应水龙头。

      测试于:Xcode 14.1,iOS 16.1

      struct KeyboardDismissSampleView: View {
          
          @Environment(\.dismissSearch) private var dismissSearch
          
          @State var searchText: String = ""
          @State var showDetailView = false
          
          var body: some View {
              NavigationView {
                  ScrollView {
                      NavigationLink(isActive: $showDetailView) {
                          Text("showDetailView")
                      } label: {
                          EmptyView()
                      }
      
                      VStack(alignment: .leading, spacing: 15) {
                          ForEach(0..<50) { i in
                              
                              // Version A
      //                        NavigationLink {
      //                            Text("Row \(i)")
      //                        } label: {
      //                            Text("Row \(i)")
      //                                .frame(maxWidth: .infinity, alignment: .leading)
      //                        }
                              
                              // Version B
                              Button("Row \(i)") {
      //                            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                                  dismissSearch()
                                  showDetailView = true
                              }
                              .frame(maxWidth: .infinity, alignment: .leading)
                          }
                      }
                      .padding()
                  }
                  .safeAreaInset(edge: .bottom, content: {
                      // This view is just to visually show the issue
                      // Even without his safeAreaInset section, the area covered by the keyboard is still not responding to taps
                      Text("safeAreaInset bottom")
                          .padding()
                          .frame(maxWidth: .infinity)
                          .background(Color.yellow)
                  })
                  .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
              }
          }
      }
      

      我尝试使用 resignFirstResponder 和 dismissSearch,它们要么有相同的问题,要么引入了其他问题。此日志显示在 Xcode 控制台中,显然您不能同时关闭键盘和导航:

      pushViewController:animated: called on &lt;_TtGC7SwiftUI41StyleContextSplitViewNavigationControllerVS_19SidebarStyleContext_ 0x10f01c600&gt; while an existing transition or presentation is occurring; the navigation stack will not be updated.

      我看过这些相关的问题:

      Keyboard dismiss not working properly when dismiss the view swiftui

      Keyboard not dismissing in SwiftUI with onTapGesture

      SwiftUI: dismiss List searchable keyboard?

【问题讨论】:

    标签: ios swift swiftui navigation keyboard


    【解决方案1】:

    看起来

    UIApplication.shared.windows.first?.endEditing(true)
    

    解决了问题,尽管它确实会生成弃用警告。

    请注意,我删除了注释掉的代码并将 NavigationView 替换为新的 NavigationStack,但这并没有解决问题。

    struct ContentView: View {
        
        @State var searchText: String = ""
        @State private var path = NavigationPath()
        
        var body: some View {
            NavigationStack(path: $path) {
                ScrollView {
                    VStack(alignment: .leading, spacing: 15) {
                        ForEach(0..<50) { i in
                            Button("Row (i)") {
                                UIApplication.shared.windows.first?.endEditing(true)
                                path.append(i)
                            }
                            .frame(maxWidth: .infinity, alignment: .leading)
                        }
                    }
                    .padding()
                }
                .navigationDestination(for: Int.self) { _ in
                    Text("show detail view")
                }
                .safeAreaInset(edge: .bottom) {
                    Text("safeAreaInset bottom")
                        .padding()
                        .frame(maxWidth: .infinity)
                        .background(Color.yellow)
                    
                }
            }
            .searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-27
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多