Swift 4:来自 UITextField 和自定义对象数组的 NSPredicate
Swift 4: NSPredicate from UITextField and array of custom object
我有一组自定义对象。
class MyObject {
var code: String!
var name: String!
}
我想autocomplete
一个textField
,因为我有一个tableView
,当用户开始写作时我会显示它。我必须根据 textField.text
过滤我的数组数据源。为此,我向 textField
添加了一个选择器,然后我使用 NSPredicate
.
测试数组中是否存在包含 textFiled.text
的元素名称
这是文本字段选择器:
@objc func textFieldDidChange(_ textField: UITextField) {
if (textField.text?.count != 0 && textField.text != " ") {
let resultPredicate = NSPredicate(format: "ANY name CONTAINS[c] %@", self.countryTextField.text!)
print("resultPredicate \(resultPredicate)")
//self.allDatasource type is [MyObject]
self.filtredDatasource = self.allDatasource.filter({
return resultPredicate.evaluate(with: [=12=].name)
})
} else {
self.filtredDatasource = self.allDatasource
}
self.tableView.reloadData()
}
当我开始写名字时,应用程序因以下错误而崩溃:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x6040004215e0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.'
所以问题出在NSPredicate format
。我搜索了这个问题,发现我可以使用 ANY
然后输入我要检查的字段名称。
我错了吗?我该如何解决这个问题?
注意:我正在使用 Swift 4
你可以试试这样过滤
let searchText = self.countryTextField.text
self.filtredDatasource = self.allDatasource.filter { ([=10=].name as! String).range(of: searchText!, options: [.diacriticInsensitive, .caseInsensitive]) != nil }
我认为要使其正常工作,您需要让 Objective-C 端可以使用您的对象:
class MyObject: NSObject {
init(code: String, name: String) {
self.code = code
self.name = name
}
var code: String
@objc var name: String
}
谓词是根据您给它的对象求值的。在你的例子中,你提供了一个 String
。对于要检查的谓词,您应该使用 self
:
let resultPredicate = NSPredicate(format: "self contains[cd] %@", searchText)
let filtered = allDatasource.filter {
resultPredicate.evaluate(with: [=11=].name)
}
你也可以给它一个MyObject来求值,然后你就可以使用属性:
的名字
let resultPredicate = NSPredicate(format: "name contains[cd] %@", searchText)
let filtered = allDatasource.filter {
resultPredicate.evaluate(with: [=12=])
}
在您的代码中,您使用了 ANY
修饰符。这是一个修饰符,您可以使用它来检查集合中是否有 any 项目符合谓词:
let searchText = "n2"
let resultPredicate = NSPredicate(format: "ANY name contains[cd] %@", searchText)
let allDatasource = [ MyObject(code: "c1", name: "n1"), MyObject(code: "c2", name: "n2")]
let containsAnyObject = resultPredicate.evaluate(with: allDatasource)
// true for 'n2'
我有一组自定义对象。
class MyObject {
var code: String!
var name: String!
}
我想autocomplete
一个textField
,因为我有一个tableView
,当用户开始写作时我会显示它。我必须根据 textField.text
过滤我的数组数据源。为此,我向 textField
添加了一个选择器,然后我使用 NSPredicate
.
textFiled.text
的元素名称
这是文本字段选择器:
@objc func textFieldDidChange(_ textField: UITextField) {
if (textField.text?.count != 0 && textField.text != " ") {
let resultPredicate = NSPredicate(format: "ANY name CONTAINS[c] %@", self.countryTextField.text!)
print("resultPredicate \(resultPredicate)")
//self.allDatasource type is [MyObject]
self.filtredDatasource = self.allDatasource.filter({
return resultPredicate.evaluate(with: [=12=].name)
})
} else {
self.filtredDatasource = self.allDatasource
}
self.tableView.reloadData()
}
当我开始写名字时,应用程序因以下错误而崩溃:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x6040004215e0> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.'
所以问题出在NSPredicate format
。我搜索了这个问题,发现我可以使用 ANY
然后输入我要检查的字段名称。
我错了吗?我该如何解决这个问题?
注意:我正在使用 Swift 4
你可以试试这样过滤
let searchText = self.countryTextField.text
self.filtredDatasource = self.allDatasource.filter { ([=10=].name as! String).range(of: searchText!, options: [.diacriticInsensitive, .caseInsensitive]) != nil }
我认为要使其正常工作,您需要让 Objective-C 端可以使用您的对象:
class MyObject: NSObject {
init(code: String, name: String) {
self.code = code
self.name = name
}
var code: String
@objc var name: String
}
谓词是根据您给它的对象求值的。在你的例子中,你提供了一个 String
。对于要检查的谓词,您应该使用 self
:
let resultPredicate = NSPredicate(format: "self contains[cd] %@", searchText)
let filtered = allDatasource.filter {
resultPredicate.evaluate(with: [=11=].name)
}
你也可以给它一个MyObject来求值,然后你就可以使用属性:
的名字let resultPredicate = NSPredicate(format: "name contains[cd] %@", searchText)
let filtered = allDatasource.filter {
resultPredicate.evaluate(with: [=12=])
}
在您的代码中,您使用了 ANY
修饰符。这是一个修饰符,您可以使用它来检查集合中是否有 any 项目符合谓词:
let searchText = "n2"
let resultPredicate = NSPredicate(format: "ANY name contains[cd] %@", searchText)
let allDatasource = [ MyObject(code: "c1", name: "n1"), MyObject(code: "c2", name: "n2")]
let containsAnyObject = resultPredicate.evaluate(with: allDatasource)
// true for 'n2'