I'm using the following code to search inside an array for the phrase typed in a UISearchBar and then add the content of the index that the phrase was found in to the array that will be displayed in the table view.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)enteredSearchText{
if ([enteredSearchText length] == 0) {
[wholeTextOfDoaasLive removeAllObjects]; //wholeTextOfDoaasLive is an NSMutableArray
}
else{
[wholeTextOfDoaasLive removeAllObjects];
for (NSString * string in AllWholeText) {//AllWholeText is an NSMutableArray
NSRange r = [string rangeOfString:enteredSearchText options:NSCaseInsensitiveSearch];
if (r.location != NSNotFound){
[wholeTextOfDoaasLive addObject:string];
}
}
}
[_searchResultsTable reloadData];
}
however, every index of the AllWholeText array contains large amounts of text and I don't want to add the whole object (that the searched phrase was found in) into wholeTextOfDoaasLive array. Instead, I want to only add a the found phrase plus two words before and after it into my wholeTextOfDoaasLive array. How can I do that?
So I wrote this code which just puts the searched phrase into context, if it's close to the end of the paragraph (the paragraph that is inside the index of the array) then it shows up with "few" words before it in the tableview cell, if it's not near the end then "few" words get shown after it.
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)enteredSearchText{
if ([enteredSearchText length] == 0) {
[wholeTextOfDoaasLive removeAllObjects];
}
else{
[wholeTextOfDoaasLive removeAllObjects];
for (NSString * string in AllWholeText) { //create string that holds the value in that index
NSRange r = [string rangeOfString:enteredSearchText options:NSCaseInsensitiveSearch];
NSUInteger indexOfFoundString = r.location;
NSUInteger numberOfAvailableCharactersAfterPhrase = string.length - (indexOfFoundString + 1 );
NSUInteger takeCharacters = 50; //number of characters that will show in tableview cell
foundStringIsAtTheEnd =NO;
/// START: eliminate the "out of bounds" error ///
// if the searched phrase is at the end of the text and you ask for 50 characters after it, the app to crash. So here we check if the searched phrase is the near the end or if it's far away from the end. A) if it's close to the end then show words before it. B) if it's far from the end then show words after it.
if (numberOfAvailableCharactersAfterPhrase < 50) {
takeCharacters = 40;
if (numberOfAvailableCharactersAfterPhrase < 40) {
takeCharacters = 30;
if (numberOfAvailableCharactersAfterPhrase < 30) {
takeCharacters = 20;
if (numberOfAvailableCharactersAfterPhrase < 20) { //there is less than 20 characters after the searched phrase
takeCharacters = numberOfAvailableCharactersAfterPhrase+30;
foundStringIsAtTheEnd =YES;
}
}
}
}
/// END: eliminate the "out of bounds" error ///
if (indexOfFoundString != NSNotFound){
NSString *tableViewString;
if (foundStringIsAtTheEnd == YES) {
indexOfFoundString -= 30; //to show few words before the searched phrase
tableViewString = [string substringWithRange:NSMakeRange(indexOfFoundString, takeCharacters)];
/// START: remove cropped words, we want only full words ///
NSArray *arrayStoredText = [tableViewString componentsSeparatedByString:@" "];
NSMutableArray *myMutable = [[NSMutableArray alloc]initWithArray:arrayStoredText];
[myMutable removeObjectAtIndex:0]; //cuz maybe it's a cropped word
tableViewString = @"";
tableViewString = [myMutable componentsJoinedByString:@" "];
/// END: remove cropped words, we want only full words ///
}
else{ //if searched phrase is far from the end
tableViewString = [string substringWithRange:NSMakeRange(indexOfFoundString, takeCharacters)];
NSArray *arrayStoredText = [tableViewString componentsSeparatedByString:@" "];
NSMutableArray *myMutable = [[NSMutableArray alloc]initWithArray:arrayStoredText];
[myMutable removeLastObject]; //cuz maybe it's a cropped word
tableViewString = @"";
tableViewString = [myMutable componentsJoinedByString:@" "];
}
[wholeTextOfDoaasLiveArray addObject:tableViewString];
}
}
}
[_searchResultsTable reloadData];
}
It doesn't do exactly what I originally asked for (two words instead of "few") but I think this is better for the user since this way I insure that the amount of text shown before the phrase in each cell of the tableview is approximately the same (could make it more accurate though).