实现类似于本机联系人搜索的搜索?
Implement search similar to native contacts search?
在本机联系人应用程序上,当您尝试搜索联系人时,您键入一些字符串,如果联系人的名字/姓氏/公司等以该字符串开头,则会显示联系人。
为了让事情变得更复杂,您可以输入类似 Mi Ric 的内容,然后搜索会找到 Michael Richardson。还有 Ric Mi 会给我 Michael Richardson。
我已将联系人记录复制到我的本地核心数据存储中,现在我的第一直觉是使用 NSFetchedResultsController
和一些不错的谓词。
但是我将如何处理这个谓词?如果 person 记录最多有 3 个单词,我应该用 beginsWith 查询每个单词吗?这甚至可以在一个谓词中完成吗?
这是我用于词基谓词的内容:
+ (NSPredicate *)wordBasedPredicateForString:(NSString *)searchString withProperty:(NSString *)property
{
// searchString = [searchString stringForSearch];
NSArray *searchStrings = [searchString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSMutableArray<NSPredicate *> *subPredicates = [NSMutableArray array];
for (NSString *string in searchStrings)
if (![string isEqualToString:@""]) {
NSString *mainString = [property stringByAppendingString:@" CONTAINS[cd] "];
mainString = [NSString stringWithFormat:@"%@ CONTAINS[cd] %%@",property];
NSPredicate *predicate = [NSPredicate predicateWithFormat:mainString, string];
[subPredicates addObject:predicate];
}
if ([searchString containsString:@" "] && subPredicates.count > 0) {
NSString *mainString = [property stringByAppendingString:@" CONTAINS[cd] "];
mainString = [mainString stringByAppendingString:@"' '"];
NSPredicate *emptySpacePredicate = [NSPredicate predicateWithFormat:mainString, nil];
[subPredicates addObject:emptySpacePredicate];
}
NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
return predicate;
}
假设我们有一个 Contact
对象和 name
属性
NSPredicate *namePredicate = [self wordBasedPredicateForString:searchString withProperty: @"name"];
然后过滤数组:
NSArray *results = [contacts filteredArrayUsingPredicate:namePredicate];
当然,您可以为名称、公司、地址等创建多个词基谓词,并像这样创建一个复合谓词:
orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[namePredicate, addressPredicate, phonePredicate]];
希望对您有所帮助 ;)
您也可以试试这个解决方案
我们来看看MyContact
class
class MyContact: NSManagedObject {
@NSManaged var contact_id: String // Primary key
@NSManaged var firstname: String
@NSManaged var lastname: String
var fullName: String {
return firstname + " " + lastname
}
}
现在您的对象中有 fullName
个字符串。所以你可以很容易地在它上面触发谓词。没关系,您的 searchString
与您的名字或姓氏匹配。
现在添加搜索逻辑:-
var currentContacts : [MyContact] = []
var contacts : [MyContact] = []
您的 tableView 委托方法使用了 currentContacts
数组和 contacts
数组来保存所有联系人。
您可以根据搜索字符串过滤 contacts
数组。
currentContacts = contacts.filter { (element: MyContact) -> Bool in
return element.fullName.localizedCaseInsensitiveContainsString(searchString)
}
tableView.reloadData()
希望对您有所帮助 ;)
在本机联系人应用程序上,当您尝试搜索联系人时,您键入一些字符串,如果联系人的名字/姓氏/公司等以该字符串开头,则会显示联系人。
为了让事情变得更复杂,您可以输入类似 Mi Ric 的内容,然后搜索会找到 Michael Richardson。还有 Ric Mi 会给我 Michael Richardson。
我已将联系人记录复制到我的本地核心数据存储中,现在我的第一直觉是使用 NSFetchedResultsController
和一些不错的谓词。
但是我将如何处理这个谓词?如果 person 记录最多有 3 个单词,我应该用 beginsWith 查询每个单词吗?这甚至可以在一个谓词中完成吗?
这是我用于词基谓词的内容:
+ (NSPredicate *)wordBasedPredicateForString:(NSString *)searchString withProperty:(NSString *)property
{
// searchString = [searchString stringForSearch];
NSArray *searchStrings = [searchString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSMutableArray<NSPredicate *> *subPredicates = [NSMutableArray array];
for (NSString *string in searchStrings)
if (![string isEqualToString:@""]) {
NSString *mainString = [property stringByAppendingString:@" CONTAINS[cd] "];
mainString = [NSString stringWithFormat:@"%@ CONTAINS[cd] %%@",property];
NSPredicate *predicate = [NSPredicate predicateWithFormat:mainString, string];
[subPredicates addObject:predicate];
}
if ([searchString containsString:@" "] && subPredicates.count > 0) {
NSString *mainString = [property stringByAppendingString:@" CONTAINS[cd] "];
mainString = [mainString stringByAppendingString:@"' '"];
NSPredicate *emptySpacePredicate = [NSPredicate predicateWithFormat:mainString, nil];
[subPredicates addObject:emptySpacePredicate];
}
NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subPredicates];
return predicate;
}
假设我们有一个 Contact
对象和 name
属性
NSPredicate *namePredicate = [self wordBasedPredicateForString:searchString withProperty: @"name"];
然后过滤数组:
NSArray *results = [contacts filteredArrayUsingPredicate:namePredicate];
当然,您可以为名称、公司、地址等创建多个词基谓词,并像这样创建一个复合谓词:
orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[namePredicate, addressPredicate, phonePredicate]];
希望对您有所帮助 ;)
您也可以试试这个解决方案
我们来看看MyContact
class
class MyContact: NSManagedObject {
@NSManaged var contact_id: String // Primary key
@NSManaged var firstname: String
@NSManaged var lastname: String
var fullName: String {
return firstname + " " + lastname
}
}
现在您的对象中有 fullName
个字符串。所以你可以很容易地在它上面触发谓词。没关系,您的 searchString
与您的名字或姓氏匹配。
现在添加搜索逻辑:-
var currentContacts : [MyContact] = []
var contacts : [MyContact] = []
您的 tableView 委托方法使用了 currentContacts
数组和 contacts
数组来保存所有联系人。
您可以根据搜索字符串过滤 contacts
数组。
currentContacts = contacts.filter { (element: MyContact) -> Bool in
return element.fullName.localizedCaseInsensitiveContainsString(searchString)
}
tableView.reloadData()
希望对您有所帮助 ;)