SwiftUI(iOS16):如何自定义.navigationLink类型Picker的最终视图?
解决方案
核心问题修复:单独控制Picker跳转视图的标题
原来的.navigationTitle直接加在Picker上,会导致原视图和跳转后的选择视图共享标题。解决办法是把Picker的选择列表抽成独立视图,仅在这个独立视图上设置标题,原视图不绑定该标题。
实现Section与搜索功能
通过Section包裹选项列表,配合.searchable修饰符实现搜索,同时用状态变量存储搜索文本并过滤数据。
完整代码示例
import SwiftUI struct SomeView: View { struct ItemStruct: Hashable { var name: String } let items = [ ItemStruct(name: "1"), ItemStruct(name: "2"), ItemStruct(name: "10"), ItemStruct(name: "20") ] @State var selection: ItemStruct? = nil var body: some View { NavigationStack { // 使用iOS16+推荐的NavigationStack List { Picker("", selection: $selection) { // 手动指定跳转目标为自定义选择视图 NavigationLink(value: selection) { Text(selection?.name ?? "请选择") .frame(width: 40, height: 40) .foregroundColor(.black) .font(.largeTitle) } } .pickerStyle(.navigationLink) } .navigationDestination(for: ItemStruct?.self) { _ in SelectionView(items: items, selection: $selection) } .onAppear { selection = items.first } } } } // 独立的Picker选择视图,集中处理标题、Section和搜索逻辑 struct SelectionView: View { let items: [SomeView.ItemStruct] @Binding var selection: SomeView.ItemStruct? @State private var searchText = "" // 根据搜索文本过滤选项 private var filteredItems: [SomeView.ItemStruct] { searchText.isEmpty ? items : items.filter { $0.name.localizedCaseInsensitiveContains(searchText) } } var body: some View { List { Section(header: Text("选项列表")) { // 添加分组Section ForEach(filteredItems, id: \.self) { item in Text(item.name) .frame(width: 40, height: 40) .foregroundColor(.black) .font(.largeTitle) .onTapGesture { selection = item // 选择后自动返回原视图 UIApplication.shared.windows.first?.rootViewController?.presentedViewController?.dismiss(animated: true) } } } } .navigationTitle("SomeTitle") // 仅在选择视图显示标题 .searchable(text: $searchText, prompt: "搜索选项") // 启用搜索功能 } } struct SomeView_Previews: PreviewProvider { static var previews: some View { SomeView() } }
关键修改说明
- NavigationStack+navigationDestination:替代Picker自动跳转逻辑,手动指定跳转目标为自定义视图,确保标题仅在选择页面生效。
- 独立SelectionView:把标题、Section、搜索逻辑集中在该视图,原视图只负责展示当前选中结果。
- 搜索功能:通过
searchText状态变量动态过滤数据源,localizedCaseInsensitiveContains实现不区分大小写的模糊匹配。 - Section分组:用
Section给选项列表添加分组头部,优化UI层级。 - 选择后自动返回:点击选项后手动关闭模态视图,提升交互流畅度。
内容的提问来源于stack exchange,提问作者Kirill
相关产品推荐
相关产品推荐

