iOS开发

UITableView的右侧索引效果

2017-11-15  本文已影响273人  nemie

在设计到联系人或者选择城市这些列表的时候,经常会看到这种效果:


图片.png

这是一组数据源 [@"阿福",@"宝宝",@"大明", @"孙s", @"李龙", @"冠军", @"温馨", @"赵长明",@"cs", @"bg", @"lk", @"sg", @"##号"]。
这个效果有两个关键问题,第一是展示右侧索引,并且要提供点击每个字母的事件。第二是将数据源按字母分成不同的组,并在tableview的代理方法中返回。
针对第一个问题, 事实上,伟大的UITableView已经封装好了这个效果,直接调用Api就可以实现右侧的索引效果,并且可以指定文字颜色,索引的背景颜色,以及点击每个索引字母所触发的事件。

第二个问题,Apple当然也提供了解决办法,因为这个毕竟是一个太常见的需求了。从iOS3.0开始,苹果提供了一个UILocalizedIndexedCollation对象来管理索引。它就是配合tableview使用的。
这个对象很强大,提供了返回包含A-Z 字母的数组,和返回汉字的拼音首字母 以及按汉字的拼音首字母进行排序的功能,真是太实用了。有了这个对象,结合tableview的Api,实现这个效果简直不需要多少行代码。
先按官方文档做个介绍:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];
}
 
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
 
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex
}

直接上代码


图片.png

定义了一个模型,name接收数据源的字符串。
控制器中首先定义全局变量

@interface ViewController () <UITableViewDelegate,UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableview;

@property (nonatomic, strong) NSMutableArray *sectionArr;

@end

@implementation ViewController {
    
    //全局索引集合
    UILocalizedIndexedCollation *collation;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    

    NSArray *testArr = @[@"阿福",@"宝宝",@"大明", @"孙s", @"李龙", @"冠军", @"温馨", @"赵长明",@"cs", @"bg", @"lk", @"sg", @"##号"];
    NSMutableArray *personArr = [NSMutableArray arrayWithCapacity:testArr.count];
    
    
    for (NSString *str in testArr) {
        Object *v = [[Object alloc] init];
        v.name = str;
        
        [personArr addObject:v];
    }
    
    //初始化UILocalizedIndexedCollation对象
    collation = [UILocalizedIndexedCollation currentCollation];
    //这个对象中包含26个大写字母A-Z 和 #
    NSArray *titles = collation.sectionTitles;
    
    //定义一个二维数组,数组中的共有27个元素,每个元素又是一个数组,分别对应字母A、B、C、D...#的数据
    NSMutableArray *secionArray = [NSMutableArray arrayWithCapacity:titles.count];
    //向二维数组中添加小数组
    for (int i = 0; i < titles.count; i++) {
        NSMutableArray *subArr = [NSMutableArray array];
        [secionArray addObject:subArr];
    }
    
    for (Object *v in personArr) {
        //这个方法会根据@selector中的方法返回的字符串的拼音首字母,找到这个首字母对应的下标index
        NSInteger section = [collation sectionForObject:v collationStringSelector:@selector(name)];
        //根据index取出二维数组中的一维数组数组元素
        NSMutableArray *subArr = secionArray[section];
        //将这个对象加入到一维数组数组中  也就是以字母A开头的对象如阿福会被加入到A字母所对应数组,其他字母同理
        [subArr addObject:v];
    }
    
    //遍历二维数组,取出每一个一维数组,在对数组中的对象按照字母进行下排序。
    for (NSMutableArray *arr in secionArray) {
        
        NSArray *sortArr = [collation sortedArrayFromArray:arr collationStringSelector:@selector(name)];
        
        [arr removeAllObjects];
        [arr addObjectsFromArray:sortArr];
    }
    
    _sectionArr = secionArray;
    
    //定义tableview右侧section的外观
    //文字颜色
    _tableview.sectionIndexColor = [UIColor blackColor];
    //背景颜色
    _tableview.sectionIndexBackgroundColor = [UIColor clearColor];
   //触摸section区域时候的背景颜色 _tableview.sectionIndexTrackingBackgroundColor = [UIColor greenColor];
    _tableview.sectionIndexMinimumDisplayRowCount = 13;
}

tableview的delegate和datasource方法

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    
    return [collation sectionTitles].count;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    return [[_sectionArr objectAtIndex:section] count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *cellid = @"cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellid];
    
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellid];
    }
    
    Object *v = [[_sectionArr objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    
    cell.textLabel.text = v.name;
    
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    
    return [_sectionArr[section] count] == 0 ? 0 : 15;
}

/**返回右侧索引所包含的内容*/
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    NSMutableArray *sections = [collation.sectionTitles mutableCopy];
    
    //往索引数组的开始处添加一个放大镜🔍 放大镜是系统定义好的一个常量字符串表示UITableViewIndexSearch 当然除了放大镜外也可以添加其他文字
    [sections insertObject:UITableViewIndexSearch  atIndex:0];
    return sections;
    
}

//返回每个section的title
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    
    return [[collation sectionTitles] objectAtIndex:section];
}

//点击右侧索引后跳转到的section
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    
    return 0;
}

代码地址 :https://gitee.com/helantage/tableviewYouCeSuoYinXiaoGuo.git

PS:
感觉tableview的索引条将表视图往左边挤了一点?别担心,只是颜色问题。只要如此设置即可

 

    //索引条背景的颜色(清空颜色就不会感觉索引条将tableview往左边挤)

        [_tableView setSectionIndexBackgroundColor:[UIColor clearColor]];

        //索引条文字的颜色

        [_tableView setSectionIndexColor:[UIColor darkGrayColor]];
上一篇下一篇

猜你喜欢

热点阅读