通讯录 分组排序、搜索


定义的无意义数据:

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


最终效果:



















goyohol's essay

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342