2017-03-28 24 views
3

ネイティブの連絡先アプリでは、連絡先を検索しようとすると文字列を入力し、名字/姓/会社などに連絡するとこの文字列で始まる場合は連絡先が表示されます。ネイティブ連絡先検索と同様の検索を実装しますか?

問題をもっと複雑にするには、Mi Ricのようなものを入力すれば検索でMichael Richardsonが見つかります。また、Ric Miが私にマイケル・リチャードソンを連れてきます。

ローカルのコアデータストアに連絡先レコードのコピーを作成しましたが、今では私の最初の本能はNSFetchedResultsControllerと素晴らしいプレディケートを使用することです。

しかし、この述語についてはどうすればよいですか?人の記録が3語まであれば、startsWithで各単語を照会する必要がありますか?これは私が1つの述語でさえできるのですか?ここで

+2

あなたは述語で正規表現を使用することができます。私はそこに可能な答えを掲示した:http://stackoverflow.com/questions/42156932/how-to-make-search-bar-as-iphone-contact-app-or-search-bar-which-handles-more-th/42162841#42162841 – Larme

答えて

3

は私が単語ベースの述語のために使用するものです。

NSArray *results = [contacts filteredArrayUsingPredicate:namePredicate]; 

+ (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; 
} 

は、私たちがその配列をフィルタリングnameプロパティ

NSPredicate *namePredicate = [self wordBasedPredicateForString:searchString withProperty: @"name"]; 

Contactオブジェクトを持っていると仮定しましょう

もちろん、名前に複数の単語ベースの述語を作ることができます。c ompany、アドレスなどと、このような1 compoundPredicateます

orPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[namePredicate, addressPredicate, phonePredicate]]; 

はそれに役立つことを願っています。)

1

また

のはMyContactクラスの

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() 

はそれに役立つことを願っています。)

関連する問題