SwiftUI中点击NavigationLink跳转后List视图下移的问题求助
SwiftUI List返回后整体向下偏移的解决办法
我用SwiftUI开发搜索视图时遇到一个问题:视图内的List通过ForEach填充数据,每行的NavigationLink跳转到新视图后,点击返回按钮回到原视图时,List会整体向下偏移。
我尝试过将视图嵌套在ScrollView中,但这导致List直接消失(查阅资料得知这是List嵌套ScrollView的正常表现);移除List仅保留ForEach时,导航功能正常,说明问题确实出在List上。我希望继续使用原生List(因其创建Section更便捷),求可行的解决办法。
相关代码
struct SearchView: View { @Binding var isSearching : Bool @FocusState var isFocused : Bool @StateObject var viewModel = SearchVM() var body: some View { VStack{ HStack{ VStack{ HStack{ Image(systemName: "magnifyingglass") .foregroundStyle(Color.secondaryColor) TextField("Pesquisar...", text: $viewModel.searchText ) .focused($isFocused) }.modifier(OutlinedCardStyle(padding: 12)) } .textFont(style: .montserrat14) Button(action: { withAnimation(.easeOut(duration: 0.4)) { isSearching.toggle() isFocused = isSearching } }, label: { Text("Cancelar") .bold() }).padding(.leading,5) }.padding([.horizontal,.top]) List { ForEach($viewModel.matchedSections, id: \.id) { $section in Section($section.sectionName.wrappedValue){ ForEach($section.subSections, id: \.id){ subsection in NavigationLink{ AppointmentView() }label:{ Text(subsection.sectionName.wrappedValue) } } } } } .listStyle(.plain) .animation(.smooth, value: viewModel.matchedSections) Spacer() } .onAppear{ isFocused = isSearching } } }
可行解决办法
调整动画作用范围
原代码将动画直接绑定在List上,可能和导航跳转的动画产生冲突。可以把动画移到ForEach层级,只针对数据变化的部分执行动画:List { ForEach($viewModel.matchedSections, id: \.id) { $section in Section($section.sectionName.wrappedValue){ ForEach($section.subSections, id: \.id){ subsection in NavigationLink{ AppointmentView() }label:{ Text(subsection.sectionName.wrappedValue) } } } } .animation(.smooth, value: viewModel.matchedSections) // 动画移至此处 } .listStyle(.plain)重置焦点状态
在离开SearchView时重置焦点,避免键盘相关的布局残留导致返回时偏移:VStack{ // ... 原有内容 } .onAppear{ isFocused = isSearching } .onDisappear{ isFocused = false }禁止键盘滚动关闭
给List添加scrollDismissesKeyboard(.never),避免键盘交互引发的布局偏移:List { // ... 原有内容 } .listStyle(.plain) .scrollDismissesKeyboard(.never) .animation(.smooth, value: viewModel.matchedSections)固定导航栏样式
如果SearchView嵌入在NavigationStack中,明确设置导航栏的显示模式,固定其高度:VStack{ // ... 原有内容 } .navigationBarTitleDisplayMode(.inline) .navigationBarHidden(false)
内容的提问来源于stack exchange,提问作者Daniel Ishida
相关产品推荐
相关产品推荐

