ios实现搜索关键字高亮效果

2020-01-21 04:34:49王冬梅

匹配的过程是一个重难点,分别进行汉字直接匹配、拼音全拼匹配、拼音简拼匹配


+ (WPFSearchResultModel *)searchEffectiveResultWithSearchString:(NSString *)searchStrLower
              nameString:(NSString *)nameStrLower
            completeSpelling:(NSString *)completeSpelling
             initialString:(NSString *)initialString
           pinyinLocationString:(NSString *)pinyinLocationString
           initialLocationString:(NSString *)initialLocationString {
 
 WPFSearchResultModel *searchModel = [[WPFSearchResultModel alloc] init];
 
 NSArray *completeSpellingArray = [pinyinLocationString componentsSeparatedByString:@","];
 NSArray *pinyinFirstLetterLocationArray = [initialLocationString componentsSeparatedByString:@","];
 
 // 完全中文匹配范围
 NSRange chineseRange = [nameStrLower rangeOfString:searchStrLower];
 // 拼音全拼匹配范围
 NSRange complateRange = [completeSpelling rangeOfString:searchStrLower];
 // 拼音首字母匹配范围
 NSRange initialRange = [initialString rangeOfString:searchStrLower];
 
 // 汉字直接匹配
 if (chineseRange.length!=0) {
  searchModel.highlightedRange = chineseRange;
  searchModel.matchType = MatchTypeChinese;
  return searchModel;
 }
 
 NSRange highlightedRange = NSMakeRange(0, 0);
 
 // MARK: 拼音全拼匹配
 if (complateRange.length != 0) {
  if (complateRange.location == 0) {
   // 拼音首字母匹配从0开始,即搜索的关键字与该数据源第一个汉字匹配到,所以高亮范围从0开始
   highlightedRange = NSMakeRange(0, [completeSpellingArray[complateRange.length-1] integerValue] +1);
   
  } else {
   /** 如果该拼音字符是一个汉字的首个字符,如搜索“g”,
    * 就要匹配出“gai”、“ge”等“g”开头的拼音对应的字符,
    * 而不应该匹配到“wang”、“feng”等非”g“开头的拼音对应的字符
    */
   NSInteger currentLocation = [completeSpellingArray[complateRange.location] integerValue];
   NSInteger lastLocation = [completeSpellingArray[complateRange.location-1] integerValue];
   if (currentLocation != lastLocation) {
    // 高亮范围从匹配到的第一个关键字开始
    highlightedRange = NSMakeRange(currentLocation, [completeSpellingArray[complateRange.length+complateRange.location -1] integerValue] - currentLocation +1);
   }
  }
  searchModel.highlightedRange = highlightedRange;
  searchModel.matchType = MatchTypeComplate;
  if (highlightedRange.length!=0) {
   return searchModel;
  }
 } 
 // MARK: 拼音首字母匹配
 if (initialRange.length!=0) {
  NSInteger currentLocation = [pinyinFirstLetterLocationArray[initialRange.location] integerValue];
  NSInteger highlightedLength;
  if (initialRange.location ==0) {
   highlightedLength = [pinyinFirstLetterLocationArray[initialRange.length-1] integerValue]-currentLocation +1;
   // 拼音首字母匹配从0开始,即搜索的关键字与该数据源第一个汉字匹配到,所以高亮范围从0开始
   highlightedRange = NSMakeRange(0, highlightedLength);
  } else {
   highlightedLength = [pinyinFirstLetterLocationArray[initialRange.length+initialRange.location-1] integerValue]-currentLocation +1;
   // 高亮范围从匹配到的第一个关键字开始
   highlightedRange = NSMakeRange(currentLocation, highlightedLength);
  }
  searchModel.highlightedRange = highlightedRange;
  searchModel.matchType = MatchTypeInitial;
  if (highlightedRange.length!=0) {
   return searchModel;
  }
 }
 searchModel.highlightedRange = NSMakeRange(0, 0);
 searchModel.matchType = NSIntegerMax;
 return searchModel;
}