如何基于两个UITextField实现Realm反向查询,过滤Items多配料属性?
实现基于两个UITextField的Realm反向查询
嘿,我来帮你搞定这个需求!咱们一步步来实现从Realm中根据两个文本框输入过滤Items数据的功能。
第一步:处理文本输入,获取有效查询关键词
首先要确保我们拿到的是干净的输入值,过滤掉空格和空字符串,避免无效查询:
@IBAction func performSearch(_ sender: UIButton) { // 获取两个文本框的输入,去除首尾空格 guard let keyword1 = ingredient1TextField.text?.trimmingCharacters(in: .whitespacesAndNewlines), let keyword2 = ingredient2TextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) else { // 处理输入为空的情况,比如直接显示所有数据 items = realm.objects(Items.self) updateUI() // 假设你有更新UI的自定义方法 return } // 如果两个关键词都为空,直接显示全部数据 if keyword1.isEmpty && keyword2.isEmpty { items = realm.objects(Items.self) updateUI() return } // 接下来构建查询条件... }
第二步:构建Realm查询条件
我们的核心目标是:只要Items对象的ingredient1到ingredient6中任意一个属性匹配关键词,就保留该对象。这里分两种常见场景给你方案:
先做个小优化:避免重复代码
把所有配料属性名存成数组,这样不用重复写6次相同的逻辑:
let ingredientKeys = ["ingredient1", "ingredient2", "ingredient3", "ingredient4", "ingredient5", "ingredient6"]
场景1:匹配任意一个关键词即可
如果只要两个关键词中有一个出现在任意配料里,就过滤出该对象:
// 为每个关键词生成「任意配料包含该关键词」的OR条件 let predicatesForKeyword1 = ingredientKeys.map { NSPredicate(format: "%K CONTAINS[cd] %@", $0, keyword1) } let predicatesForKeyword2 = ingredientKeys.map { NSPredicate(format: "%K CONTAINS[cd] %@", $0, keyword2) } // 根据输入情况合并条件 let combinedPredicate: NSPredicate if keyword1.isEmpty { // 只有第二个关键词有值,只用它的条件 combinedPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicatesForKeyword2) } else if keyword2.isEmpty { // 只有第一个关键词有值,只用它的条件 combinedPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicatesForKeyword1) } else { // 两个关键词都有值,合并所有OR条件 combinedPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicatesForKeyword1 + predicatesForKeyword2) }
场景2:必须同时匹配两个关键词
如果需要对象的配料里同时包含两个关键词(不管是不是同一个配料):
// 分别生成「任意配料包含关键词1」和「任意配料包含关键词2」的独立条件 let predicate1 = NSCompoundPredicate(orPredicateWithSubpredicates: predicatesForKeyword1) let predicate2 = NSCompoundPredicate(orPredicateWithSubpredicates: predicatesForKeyword2) // 要求两个条件必须同时满足 let combinedPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1, predicate2])
第三步:执行查询并更新UI
最后用构建好的谓词过滤Realm数据,然后刷新UI:
// 执行Realm查询 items = realm.objects(Items.self).filter(combinedPredicate) // 更新UI,比如刷新tableView或者其他展示组件 updateUI()
额外小提示
CONTAINS[cd]中的[cd]表示忽略大小写和重音符号,如果你需要精确匹配(区分大小写),可以改成CONTAINS,或者用==做完全匹配。- Realm的
Results是实时更新的,只要Realm中的数据变化,items会自动同步,无需手动刷新。 - 如果你的查询是在后台线程执行的,要注意每个线程使用独立的Realm实例,不要跨线程传递
Results对象。
内容的提问来源于stack exchange,提问作者Kabalry
相关产品推荐
相关产品推荐

