You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 12:25:14