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

如何在SwiftUI的searchable搜索栏中结合>、<符号实现金额范围筛选

如何在SwiftUI的searchable搜索栏中结合>、<符号实现金额范围筛选

我来帮你搞定这个金额筛选的需求!你想要在搜索栏里输入>50或者<30这样的指令,过滤出符合条件的交易列表对吧?咱们先看看原来代码里的问题,再一步步调整:

原来代码的问题

你之前写的searchResult里的过滤逻辑有点问题:

queryList.filter({$0.amount >= (Double(searchQuery) ?? 0) || $0.amount <= Double(searchQuery) ?? 0})

这个逻辑其实会返回所有数据——因为任何一个金额要么大于等于某个数,要么小于等于某个数,等于没做筛选。咱们得先从搜索字符串里解析出操作符(>或<)和目标金额,再针对性过滤。

修改后的实现方案

咱们重新写searchResult的计算属性,先解析搜索指令,再根据操作符过滤:

var searchResult: [Items] {
    guard !searchQuery.isEmpty else { return queryList }
    
    // 提取操作符和目标金额字符串,顺便去掉多余空格
    let firstChar = searchQuery.first!
    let amountString = String(searchQuery.dropFirst()).trimmingCharacters(in: .whitespaces)
    
    // 把金额字符串转成Double,解析失败则返回所有数据
    guard let targetAmount = Double(amountString) else {
        return queryList
    }
    
    // 根据操作符执行对应过滤逻辑
    switch firstChar {
    case ">":
        return queryList.filter { $0.amount >= targetAmount }
    case "<":
        return queryList.filter { $0.amount <= targetAmount }
    default:
        // 没有操作符的情况,比如直接输入`50`,这里默认返回金额等于该值的项,可按需调整
        return queryList.filter { $0.amount == targetAmount }
    }
}

代码说明

  • 首先判断搜索框是否为空,空的话直接返回所有交易;
  • 取出搜索字符串的第一个字符作为操作符,剩下的部分去掉空格后转成目标金额(支持用户输入> 50这种带空格的指令);
  • 如果金额解析失败(比如输入>abc),就返回所有数据(你也可以改成返回空列表,看你的需求);
  • 针对>和<分别过滤出大于等于和小于等于目标金额的交易;
  • 对于没有操作符的输入(比如直接输50),这里默认返回金额刚好等于50的项,你可以根据需求改成其他逻辑(比如包含该金额的模糊匹配)。

完整的ContentView代码

替换掉原来的searchResult后,完整代码是这样的:

import SwiftUI

struct Items: Identifiable {
    let id = UUID().uuidString
    let name: String
    let amount: Double
    
    static var samples: [Items] = [
        Items(name: "item 1", amount: 10.9),
        Items(name: "item 2", amount: 50.0),
        Items(name: "item 3", amount: 30.7),
        Items(name: "item 4", amount: -10.9),
        Items(name: "item 5", amount: 80.3),
        Items(name: "item 6", amount: 15.3),
        Items(name: "item 7", amount: 80.0),
    ]
}

struct ContentView: View {
    @State var queryList: [Items] = Items.samples
    @State var searchQuery = ""
    
    var searchResult: [Items] {
        guard !searchQuery.isEmpty else { return queryList }
        
        let firstChar = searchQuery.first!
        let amountString = String(searchQuery.dropFirst()).trimmingCharacters(in: .whitespaces)
        
        guard let targetAmount = Double(amountString) else {
            return queryList
        }
        
        switch firstChar {
        case ">":
            return queryList.filter { $0.amount >= targetAmount }
        case "<":
            return queryList.filter { $0.amount <= targetAmount }
        default:
            return queryList.filter { $0.amount == targetAmount }
        }
    }
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(searchResult) { list in
                    HStack {
                        Text(list.name)
                        Spacer()
                        Text("\(list.amount)")
                    }
                }
            }
            .listStyle(.plain)
            .searchable(text: $searchQuery)
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

现在测试一下:输入>50会显示item2(50.0)、item5(80.3)、item7(80.0);输入<30会显示item1(10.9)、item4(-10.9)、item6(15.3),完全符合你的需求啦!

备注:内容来源于stack exchange,提问作者mzkn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 08:39:38