2013-11-22 31 views
1

在我的iOS應用程序中,我已經實現了核心數據和搜索欄的表格視圖。在當前狀態下,搜索僅顯示以搜索字符串開頭的字段,但我想要顯示包含至少三個字符長度的搜索文本的字段。NSComparisonResult選項

That's是我的搜索功能代碼:

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope 
{ 
    NSLog(@"Previous Search Results were removed."); 
    [self.searchResults removeAllObjects]; 

    for (Person *person in [self.fetchedResultsController fetchedObjects]) 
    { 
     if ([scope isEqualToString:@"All"] || [person.firstname isEqualToString:scope]) 
     { 
      NSComparisonResult result = [person.firstname compare:searchText 
                options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) 
                range:NSMakeRange(0, [searchText length])]; 
      if (result == NSOrderedSame) 
      { 
       NSLog(@"Adding person.firstname '%@' to searchResults as it begins with search text '%@'", person.firstname, searchText); 
       [self.searchResults addObject:person]; 
      } 
     } 
    } 
} 

請你們教我做搜索爲想要的方式,其中有至少三個字符的搜索字符串的任何領域長度。 謝謝。

+0

愚蠢的評論,我敢肯定,但你大概的意思是包含在同一順序搜索字符串至少有三個字符,因爲它們出現在搜索字符串?所以搜索字符串可以是「abcdef」,並且匹配「stcdepqr」而不是「edabfc」? – Tommy

+0

是的,你是對的,抱歉....謝謝你tommy :)例如:搜索字符串:#10,選定字段:任務#10 /組#101等。 – mvasco

+2

這是否意味着searchText#10會匹配與#0120匹配,因爲它與searchText匹配3個字符,或者您正在查找3個連續字符? –

回答

1

最簡單的方法,最適合您的要求,我認爲是使用一個NSPredicate過濾掉[self.fetchedResultsController fetchedObjects]陣列和用它。 NSPredicate可以應用於任何NSArray,以過濾掉向該數組實例發送filteredArrayUsingPredicate:消息的結果。所以我的建議是使用一些類似於下面的代碼:

-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope { 
self.searchResults = [[self.fetchedResultsController fetchedObjects] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 
    Person* person = evaluatedObject; 
    NSString* firstName = person.firstname; 

    //searchText having length < 3 should not be considered 
    if (!!searchText && [searchText length] < 3) { 
     return YES; 
    } 

    if ([scope isEqualToString:@"All"] || [firstName isEqualToString:scope]) { 
     return ([firstName rangeOfString:searchText].location != NSNotFound); 
    } 
    return NO; //if nothing matches 
    }]]; 
} 
+0

謝謝Ayan,但我必須問你,我應該在哪裏插入你的代碼。 – mvasco

+1

@mvasco請爲我修改'filterContentForSearchText'方法,看看我編輯的答案。 –

+0

再次感謝Ayan,但是使用您的代碼不會顯示任何過濾..沒有錯誤消息,並且應用程序不會掛斷。例如:有10條記錄,每條記錄都有一個名字段,名字字段的內容是:1.任務#1 2.任務#2 3.任務#3等等用我的代碼運行,我必須搜索整個字符串,例如:task# - >顯示全部10條記錄;任務#1 - >顯示記錄1和10,任務#1和任務#10。運行你的代碼,如果我搜索:任務#1 - >顯示所有記錄... – mvasco

1

展開了討論至少,天真蠻力方法:

// get a set of all substrings; using a set means these will be deduplicated 
NSMutableSet *substrings = [NSMutableSet set]; 
for(NSInteger index = 0; index < searchText.length - 3; index++) 
    [substrings addObject:[searchText substringWithRange:NSMakeRange(index, 3)]]; 

// search every person for every single last possibility 
[self.searchResults removeAllObjects]; 
for(Person *person in [self.fetchedResultsController fetchedObjects]) 
{ 
    // ... scope and whatever else tests here ... 

    for(NSString *string in substrings) 
    { 
     if([person.firstname rangeOfString:string].location != NSNotFound) 
     { 
      [self.searchResults addObject:person]; 
      break; // exit the string in substrings loop early 
     } 
    } 
} 
+0

謝謝湯米,讓我試試你的建議.... :)我會告訴你.. – mvasco

+0

湯米,我得到一個錯誤:沒有可見的@interface爲NSString聲明選擇器rangeOfSubstring。我的代碼的哪一部分必須由您的建議來代替? – mvasco

+1

對不起;我只是直接在這裏輸入它,顯然以前對'substringWithRange:'的調用影響了我的想法。它是'rangeOfString:',而不是'rangeOfSubstring:',因爲你傳遞的東西不一定是一個子字符串 - 它可能根本找不到。 – Tommy