Swift 4:来自UITextField的NSPredicate和自定义对象数组

时间:2018-02-15 21:56:36

标签: ios swift nspredicate

我有一个自定义对象数组。

class MyObject {
    var code: String!
    var name: String!
}

我希望autocomplete textField因为我有一个tableView,当用户开始写时我会显示textField.text。我必须根据textField过滤我的数组数据源。为此我向textFiled.text添加了一个选择器,然后使用NSPredicate测试数组中是否包含 @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: $0.name) }) } else { self.filtredDatasource = self.allDatasource } self.tableView.reloadData() } 的元素名称。

这是textField选择器:

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。我搜索了这个问题,发现我可以使用./firefox --ProfileManager 然后输入我要检查的字段名称。

我错了吗?我该如何解决这个问题?

注意:我使用的是Swift 4

2 个答案:

答案 0 :(得分:1)

你可以尝试像这样过滤

console.log("dataset:", dataset)

答案 1 :(得分:1)

我认为为了正常工作,你需要让你的对象可用于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: $0.name)
}

您还可以给它一个 MyObject 进行评估,然后您可以使用该属性的名称:

let resultPredicate = NSPredicate(format: "name contains[cd] %@", searchText)

let filtered = allDatasource.filter {
    resultPredicate.evaluate(with: $0)
}

在您的代码中,您使用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'