通讯录 分组排序、搜索

459 阅读3分钟

定义的无意义数据:

MateCellModel * model = [[MateCellModel alloc] init];
model.name = @"刘兰";
model.avatar = @"http://www.feizl.com/upload2007/2011_11/111114031172443.jpg";
model.cityName = @"成都市";
model.countyName = @"青羊区";

MateCellModel * model2 = [[MateCellModel alloc] init];
model2.name = @"张静轩";
model2.avatar = @"http://www.ghost64.com/qqtupian/zixunImg/local/2016/11/30/14804708832644.jpg";
model2.cityName = @"成都市";
model2.countyName = @"金牛区";

MateCellModel * model3 = [[MateCellModel alloc] init];
model3.name = @"李三秒";
model3.avatar = @"http://www.feizl.com/upload2007/2012_12/121225160256954.jpg";
model3.cityName = @"成都市";
model3.countyName = @"青白江区";

MateCellModel * model4 = [[MateCellModel alloc] init];
model4.name = @"安复辟";
model4.avatar = @"http://cdn.clickme.net/Gallery/2014/08/30/1a751a31715abc7777826ecb95ae6bf6.png";
model4.cityName = @"成都市";
model4.countyName = @"武侯区";

MateCellModel * model5 = [[MateCellModel alloc] init];
model5.name = @"张小禹";
model5.avatar = @"http://img.duoziwang.com/2017/04/13/B2037.jpg";
model5.cityName = @"成都市";
model5.countyName = @"锦江区";

MateCellModel * model6 = [[MateCellModel alloc] init];
model6.name = @"江程子";
model6.avatar = @"";
model6.cityName = @"成都市";
model6.countyName = @"高新区";

MateCellModel * model7 = [[MateCellModel alloc] init];
model7.name = @"蒙多";
model7.avatar = @"http://news.shangqiuw.com/upload/News/2016-7-12/201671215224938hiyak.jpg";
model7.cityName = @"成都市";
model7.countyName = @"龙泉驿区";

MateCellModel * model8 = [[MateCellModel alloc] init];
model8.name = @"刘谋";
model8.avatar = @"http://img5.duitang.com/uploads/item/201508/03/20150803104547_4JZjn.thumb.224_0.jpeg";
model8.cityName = @"成都市";
model8.countyName = @"锦江区";

MateCellModel * model9 = [[MateCellModel alloc] init];
model9.name = @"韩撒比";
model9.avatar = @"https://wanzao2.b0.upaiyun.com/system/pictures/25529295/original/7f7aa77ce7b350ef.png-550";
model9.cityName = @"成都市";
model9.countyName = @"武侯区";

MateCellModel * model10 = [[MateCellModel alloc] init];
model10.name = @"齐达内";
model10.avatar = @"http://news.7m.com.cn/news/upload_img/20090621/4uFgOdYiWG7b.jpg";
model10.cityName = @"成都市";
model10.countyName = @"锦江区";


进入主题!!

全局变量:

{
  UISearchBar * _mySearchBar;//搜索框
  UITextField * _searchField;//输入框(搜索框的)
  NSMutableArray * _saerch_DataSource;//索引(A~Z)数组

  BOOL _isUsingSearchBar;//是否在使用搜索框
}

属性:

//负责进行数据分组的原生类
@property (nonatomic, strong)UILocalizedIndexedCollation * localizedCollation;

@property (nonatomic,strong) NSMutableArray * dataArray;//全部数据
@property (nonatomic, copy)NSArray * handleContactObjects;//真正数据源:存放处理过的数组

@property (nonatomic,strong) NSMutableArray *searchResultArr;//搜索的结果

获取 定义好的搜索框(_mySearchBar)的 输入框_searchField

_searchField = [_mySearchBar valueForKey:@"_searchField"];

索引的使用:
/** 索引 */
self.matesTabV.sectionIndexColor = [UIColor colorWithRed:42.f/255.f green:170.f/255.f blue:255.f/255.f alpha:1.f];//改变索引的颜色:浅蓝色
self.matesTabV.sectionIndexBackgroundColor = [UIColor clearColor];//改变索引的背景颜色
self.matesTabV.sectionIndexTrackingBackgroundColor = [UIColor redColor];//改变索引选中时的背景颜色

//索引数组
_saerch_DataSource = [[NSMutableArray alloc] init] ;  //初始化索引数据
for(char c = 'A'; c <= 'Z'; c++ ) { //存放:`A`~`Z`
    [_saerch_DataSource addObject:[NSString stringWithFormat:@"%c",c]];
    if (c == 'Z') {
        [_saerch_DataSource addObject:[NSString stringWithFormat:@"#"] ];
    }
}


//实例化 分组的原生类
self.localizedCollation = [UILocalizedIndexedCollation currentCollation];

索引的代理设置:

//MARK:sectionIndex(UITableViewDataSource)
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 
    return _saerch_DataSource;//返回索引数组:A~Z
}


-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { 
    //响应 点击索引时的委托方法(属于DataSource)

    if (_isUsingSearchBar == NO) { //非搜索状态
        NSInteger count = 0;
//    NSLog(@"点击的标题:%@---位置:%ld",title,(long)index);

        //MBProgressHUD 显示 标题的文字
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
        hud.mode = MBProgressHUDModeText;
        hud.label.font = [UIFont boldSystemFontOfSize:35.f];
        hud.label.text = [NSString stringWithFormat:@"%@ ",_saerch_DataSource[index]];
        hud.label.textAlignment = NSTextAlignmentCenter;
        hud.label.adjustsFontSizeToFitWidth = YES;
        hud.margin = 35.f;
        hud.offset = CGPointMake(0, 0.f);
        hud.removeFromSuperViewOnHide = YES;
        [hud hideAnimated:YES afterDelay:1.f];
        hud.userInteractionEnabled = NO; //可用户交互(self.view)
    
        for(NSString *character in _saerch_DataSource) {
            if([character isEqualToString:title]) {
                return count; //点击的位置
            }
            count ++;
        }
    }

     return 0;
}

效果:字体浅蓝色,选择时背景为红色!

对tableView的代理使用:

#pragma mark - UITableViewDataSource

//搜索框有文字时,只有 一个组(section)
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (_searchField.text.length > 0) { //搜索框有文字
        return 1;
    } else {
        return _saerch_DataSource.count;//self.handleContactObjects.count
    }
}

//搜索框有文字,返回 搜索到的数组
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (_searchField.text.length > 0) { //搜索框有文字
        return self.searchResultArr.count;
    } else {
        return ((NSArray *)self.handleContactObjects[section]).count;
    }
}


//在搜索框有文字时,使用搜索文字所产生的数组:self.searchResultArr
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    MateListTableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
    if (!cell) {
        cell = [[MateListTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    if (_searchField.text.length > 0) {
        //搜索框有文字
        if (self.searchResultArr.count > 0) {
            cell.model = self.searchResultArr[indexPath.row];
        }
    
    } else {
        if (self.handleContactObjects.count > 0 && ((NSArray *)self.handleContactObjects[indexPath.section]).count > 0) {
            cell.model = ((NSArray *)self.handleContactObjects[indexPath.section])[indexPath.row];
        }

    }

    cell.selectionStyle = UITableViewCellSelectionStyleNone; //无选中色
    return cell;
}


//在使用搜索框、最终的数组为空时,隐藏 header视图(返回高度为:0)
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (_searchField.text.length > 0 ) { //在使用搜索
        return 0.f; 
    }

    if (self.handleContactObjects.count > 0 && ((NSArray *)self.handleContactObjects[section]).count == 0) {
        return 0.f; //最终的数组为空时
    }
    return SCREEN_WIDTH*60.f/750.f;
}
//设置header视图的标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return _saerch_DataSource[section];
}

点击Cell跳转到详情界面:

  • 搜索框有文字,使用搜索产生的数组self.searchResultArr
  • 搜索框无文字,使用分好组数组self.handleContactObjects

#pragma mark - UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    MateDetailInfoViewController * mateDetailInfoVC = [[MateDetailInfoViewController alloc] init];
    [self.navigationController pushViewController:mateDetailInfoVC animated:YES];

    if (_searchField.text.length > 0) { //搜索框有文字
        mateDetailInfoVC.mateCellModel = self.searchResultArr[indexPath.row];
    } else {
        mateDetailInfoVC.mateCellModel = ((NSArray *)self.handleContactObjects[indexPath.section])[indexPath.row];
    }

}

分组的使用:

self.dataArray = @[model,model2,model3,model4,model5,model6,model7,model8,model9,model10].mutableCopy;

self.handleContactObjects = [self getTheHandleContactObjects];//真正数据源:获取分好的数组

self.searchResultArr = @[].mutableCopy;//搜索的数组


[self.matesTabV reloadData];

获取分组后数组:(真正数据源) 按文字的字母顺序放置在相应的“A~Z”(section)区间!

#pragma mark - localizedCollation Setter
-(NSArray*)getTheHandleContactObjects {
    //初始化数组返回的数组
    NSMutableArray * contacts = [NSMutableArray arrayWithCapacity:0];

    /**** 根据UILocalizedIndexedCollation的27个Title放入27个存储数据的数组 ****/
    for (NSInteger i = 0; i < self.localizedCollation.sectionTitles.count; i++) {
        [contacts addObject:[NSMutableArray arrayWithCapacity:0]];
    }


    //开始遍历联系人对象,进行分组(name方法)
    for (MateCellModel * model in self.dataArray) {
        NSInteger section = [self.localizedCollation sectionForObject:model collationStringSelector:@selector(name)]; //获取名字对应section
    
        [contacts[section] addObject:model];//根据索引在相应的数组上添加数据
    }


    //对每个同组的联系人进行排序
    for (NSInteger i = 0; i < self.localizedCollation.sectionTitles.count; i++) {
        //获取 需要排序的数组
        NSMutableArray * tempMutableArray = contacts[i];
    
        //通过nameObject的name进行排序,排序器排序
        NSSortDescriptor * sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:true];
        [tempMutableArray sortUsingDescriptors:@[sortDescriptor]];
        contacts[i] = tempMutableArray;
    }

    //返回
    return [NSArray arrayWithArray:contacts];
}

最终效果:


搜索的使用:
#pragma mark - UISearchBarDelegate
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
    _mySearchBar.showsCancelButton = YES; //取消按钮(显示)
    _isUsingSearchBar = YES; //搜索框使用状态:YES

    //改变索引的颜色为:透明
    self.matesTabV.sectionIndexColor = [UIColor clearColor];
    return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
    _mySearchBar.showsCancelButton = NO;
    _isUsingSearchBar = NO; //搜索框使用状态:YES

    //设置 索引的颜色:浅蓝色
    self.matesTabV.sectionIndexColor = [UIColor colorWithRed:42.f/255.f green:170.f/255.f blue:255.f/255.f alpha:1.f];
    return YES;
}



//输入框:文字改变
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
//    NSLog(@"输入框的文字 searchText:%@",searchText);
    [self.searchResultArr removeAllObjects];

    NSMutableArray *tempResults = [NSMutableArray array];
    NSUInteger searchOptions = NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch;

    NSMutableArray *contactsSource = [NSMutableArray arrayWithArray:self.handleContactObjects]; //分好组的数组
    for (NSArray * array in contactsSource) {
        for (MateCellModel * model in array) {
            [tempResults addObject:model];
        }
    }

    for (int i = 0; i < tempResults.count; i++) {
        if (searchText.isChinese) { //全汉字
            NSString *name_storeString = [(MateCellModel *)tempResults[i] name];
            NSString *city_storeString = [(MateCellModel *)tempResults[i] cityName];
            NSString *County_storeString = [(MateCellModel *)tempResults[i] countyName];
        
            NSString * total_StoreString = [NSString stringWithFormat:@"%@%@%@",name_storeString,city_storeString,County_storeString];
            NSRange total_storeRange = NSMakeRange(0, total_StoreString.length);
            //NSRange storeRange = NSMakeRange(0,searchText.pinyin.length);
            if (total_StoreString.length < total_storeRange.length) {
                continue;
            }
        
            NSRange foundRange = [total_StoreString rangeOfString:searchText options:searchOptions range:total_storeRange];
            if (foundRange.length) { //搜索最前面: && foundRange.location == 0
            
                [self.searchResultArr addObject:tempResults[i]];
            }
        } else { //非  全汉字
            NSString *name_storeString = [[(MateCellModel *)tempResults[i] name] pinyin];
            NSString *city_storeString = [[(MateCellModel *)tempResults[i] cityName] pinyin];
            NSString *County_storeString = [[(MateCellModel *)tempResults[i] countyName] pinyin];
        
            NSString * total_StoreString = [NSString stringWithFormat:@"%@%@%@",name_storeString,city_storeString,County_storeString];
            NSRange total_storeRange = NSMakeRange(0, total_StoreString.length);
            //  NSRange storeRange = NSMakeRange(0,searchText.pinyin.length);
            if (total_StoreString.length < total_storeRange.length) {
                continue;
            }
        
            NSRange foundRange = [total_StoreString rangeOfString:searchText.pinyin options:searchOptions range:total_storeRange];
            if (foundRange.length) { //搜索最前面: && foundRange.location == 0
            
                [self.searchResultArr addObject:tempResults[i]];
            }
        }
    
    }

    [self.matesTabV reloadData];
}

//“取消”按钮
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { 
    [searchBar setText:@""];
    [searchBar resignFirstResponder];
    searchBar.prompt = nil;

    [self.searchResultArr removeAllObjects];
    [self.matesTabV reloadData];
}

判断中文的类别

#import "NSString+Chinese.h"

@implementation NSString (Chinese)

- (BOOL)isChinese//判断是否是纯汉字
{
    NSString *match = @"(^[\u4e00-\u9fa5]+$)";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match];
    return [predicate evaluateWithObject:self];
}


- (BOOL)includeChinese//判断是否含有汉字
{
    for(int i=0; i< [self length];i++)
    {
        int a =[self characterAtIndex:i];
        if( a >0x4e00&& a <0x9fff){
            return YES;
        }
    }
    return NO;
}

@end

最终效果:




2017.12.08

goyohol's essay