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

如何在SwiftUI搜索栏中为SearchResultsButton添加Sheet弹窗功能?

实现搜索栏结果按钮点击弹出Sheet的方案

SwiftUI原生的searchable修饰符没有提供搜索结果按钮的点击回调接口,我们需要借助UIKit的UISearchBarDelegate来拦截按钮点击事件,进而触发Sheet弹窗。

步骤1:自定义搜索栏代理类

先创建一个遵循UISearchBarDelegate的类,用来监听搜索结果按钮的点击动作:

import SwiftUI

class CustomSearchBarDelegate: NSObject, UISearchBarDelegate {
    var resultsButtonAction: (() -> Void)?
    
    func searchBarResultsListButtonClicked(_ searchBar: UISearchBar) {
        resultsButtonAction?()
    }
}

步骤2:修改ContentView实现功能

更新你的ContentView,添加控制Sheet显示的状态变量,绑定代理的点击回调:

struct ContentView: View {
    @State private var searchText = ""
    @State private var isResultsSheetPresented = false
    private let searchDelegate = CustomSearchBarDelegate()
    
    var body: some View {
        NavigationView {
            List {
                Text("Hello")
                Text("World")
            }
            .navigationTitle("Hello")
            .searchable(text: $searchText)
            .sheet(isPresented: $isResultsSheetPresented) {
                // 替换成你需要的Sheet内容视图
                VStack(spacing: 20) {
                    Text("搜索结果页面")
                        .font(.title)
                    Text("这里展示你的搜索结果")
                }
                .padding()
            }
            .onAppear {
                // 显示搜索结果按钮
                UISearchBar.appearance().showsSearchResultsButton = true
                
                // 递归查找视图层级中的UISearchBar并设置代理
                if let searchBar = findSearchBar(in: UIApplication.shared.windows.first?.rootViewController?.view) {
                    searchBar.delegate = searchDelegate
                }
                
                // 绑定按钮点击事件
                searchDelegate.resultsButtonAction = {
                    isResultsSheetPresented = true
                }
            }
        }
    }
    
    // 递归查找视图中的UISearchBar实例
    private func findSearchBar(in view: UIView?) -> UISearchBar? {
        guard let view = view else { return nil }
        if let searchBar = view as? UISearchBar {
            return searchBar
        }
        for subview in view.subviews {
            if let found = findSearchBar(in: subview) {
                return found
            }
        }
        return nil
    }
}

补充说明

  • findSearchBar方法通过递归遍历视图层级查找UISearchBar,比直接取子视图的方式更可靠,适配复杂视图结构。
  • Sheet中的内容可以完全自定义,比如添加搜索结果列表、筛选控件等,替换示例中的VStack即可。
  • 若使用iOS 16+,可将NavigationView替换为NavigationStack,代码逻辑保持不变。

内容的提问来源于stack exchange,提问作者user19914183

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:10:32