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

SwiftUI实现按钮触发搜索栏及切换机场ICAO标识的问题

SwiftUI内联搜索栏实现方案(替代Sheet)

核心思路是用布尔状态变量控制搜索区域的显示/隐藏,结合NavigationStack实现内联搜索,同时添加实时过滤的搜索结果列表,选中后直接更新按钮标题。

完整实现代码

import SwiftUI

// 适配API的Airport模型(根据实际返回结构调整字段)
struct Airport: Codable, Identifiable {
    let id = UUID()
    let icao: String // 对应ICAO ID,如"KLAX"
    // 可扩展字段:机场名称、地理位置等
}

struct ContentView: View {
    @State private var homeAirport: String = "KCMA"
    @State private var searchedAirport: String = ""
    @State private var isSearchActive = false // 控制搜索区域显隐
    @State private var allAirports: [Airport] = [] // 存储待搜索的机场列表
    
    // 实时过滤搜索结果
    var filteredAirports: [Airport] {
        searchedAirport.isEmpty 
            ? allAirports 
            : allAirports.filter { $0.icao.localizedCaseInsensitiveContains(searchedAirport) }
    }
    
    var body: some View {
        NavigationStack {
            VStack(alignment: .leading, spacing: 16) {
                // 机场选择按钮
                Button {
                    isSearchActive.toggle()
                    if isSearchActive { searchedAirport = "" }
                } label: {
                    Text(homeAirport)
                        .font(.largeTitle)
                        .bold()
                        .fontDesign(.monospaced)
                        .foregroundStyle(.green)
                }
                
                // 内联搜索区域
                if isSearchActive {
                    VStack(spacing: 12) {
                        TextField("输入ICAO ID搜索", text: $searchedAirport)
                            .textFieldStyle(.roundedBorder)
                            .padding(.horizontal)
                            .focused($isSearchActive) // 激活时自动聚焦输入框
                        
                        // 搜索结果列表
                        List(filteredAirports) { airport in
                            Button {
                                homeAirport = airport.icao
                                isSearchActive = false // 选中后隐藏搜索区域
                            } label: {
                                HStack {
                                    Text(airport.icao)
                                        .fontDesign(.monospaced)
                                    // 可添加机场名称等辅助信息
                                }
                            }
                        }
                        .listStyle(.plain)
                        .frame(height: 220) // 限制列表高度避免占满屏幕
                    }
                }
            }
            .padding()
            .searchable(text: $searchedAirport, prompt: "搜索机场ICAO")
            .onAppear {
                // 这里可以提前加载机场列表数据(替换为你的数据源API)
                // Task { await loadAllAirports() }
            }
        }
    }
    
    // 加载单个机场详情(保留原逻辑)
    func loadAirportDetail() async {
        guard let url = URL(string: "https://aviationweather.gov/cgi-bin/data/metar.php?ids=\(homeAirport)&hours=0&order=id%2C-obs&sep=true&elev&format=json") else {
            print("无效URL")
            return
        }
        
        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            let decoded: [Airport] = try JSONDecoder().decode([Airport].self, from: data)
            // 处理返回的机场数据
        } catch {
            print(error)
        }
    }
    
    // 加载全量机场列表用于搜索过滤
    func loadAllAirports() async {
        guard let url = URL(string: "你的全机场数据API地址") else { return }
        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            allAirports = try JSONDecoder().decode([Airport].self, from: data)
        } catch {
            print(error)
        }
    }
}

关键实现说明

  1. 内联搜索控制:用isSearchActive变量替代Sheet,实现搜索区域的切换显示,避免弹出新页面。
  2. 搜索体验优化:通过focused($isSearchActive)在显示搜索区域时自动聚焦输入框,减少用户操作步骤。
  3. 实时过滤逻辑:通过计算属性filteredAirports根据输入内容实时筛选机场,无需额外触发请求。
  4. 选中反馈:点击搜索结果后直接更新按钮标题并隐藏搜索区域,完成闭环操作。
  5. 修正NavigationStack用法:将.searchable修饰符放在导航栈内部的视图上,确保搜索功能正常触发(原代码中.task嵌套ContentView的写法错误)。

注意事项

  • 若没有全量机场API,可调整为根据输入实时请求单机场数据,但无法实现多结果过滤,建议提前缓存常用机场列表。
  • 可根据需求自定义搜索区域的样式、列表高度等UI细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 22:30:57