如何在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
相关产品推荐
相关产品推荐

