SwiftUI 点击List内NavigationLink项时如何先收起键盘再跳转
实现步骤
- 新增状态变量控制导航跳转与传值
在当前视图的属性定义区域添加两个状态变量:
// 控制详情页导航是否激活 @State private var navigateToDetail = false // 存储选中的单词信息用于传参 @State private var selectedWordInfo: (id: Int, word: String, lang: String)?
- 替换原有的隐形NavigationLink
把原来ForEach循环里每个条目下的隐形NavigationLink删掉,在List的同级位置新增统一的导航入口:
if model.dataLoaded { // 新增统一导航入口 NavigationLink(isActive: $navigateToDetail) { if let info = selectedWordInfo { WordDetailView(englishWordId: info.id, englishWord: info.word, lang: info.lang) } } label: { EmptyView() } .isDetailLink(false) List { ForEach(self.model.englishDictionaries, id: \.id) { item in ZStack { VStack(alignment: .leading, spacing: 4) { Text("\(item.value)").font(.title2) Text("\(item.pairWord)").foregroundColor(.gray).font(.caption) } } // 让整个条目区域可响应点击 .contentShape(Rectangle()) .onTapGesture { // 先收起键盘 UIApplication.shared.endEditing() // 等待系统键盘收起动画完成(默认时长0.25秒)后再触发跳转 DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { selectedWordInfo = (id: item.id, word: item.value, lang: "en") navigateToDetail = true } } } } .frame(height: reader.size.height) .animation(.linear) }
额外优化建议
- 在当前视图的
onDisappear修饰符中添加键盘收起逻辑,作为异常场景的兜底:.onDisappear { UIApplication.shared.endEditing() } - 你的现有代码中存在
List嵌套在ScrollView中的结构,List本身自带滚动能力,嵌套可能引发额外的滚动异常,建议移除外层的ScrollView仅保留List即可 - 如果需要更高的稳定性,可以监听系统
UIKeyboardDidHide通知,收到通知后再触发跳转,避免不同设备、不同自定义键盘的动画时长差异问题
内容的提问来源于stack exchange,提问作者Payam Khaninejad
相关产品推荐
相关产品推荐

