`

UITableView实现索引

 
阅读更多

效果图类似这样,普通的通讯录样式



在网上找到很多帖子,都没成功,最后还是官方的文档靠谱:

TableView PG

其实最关键的,就是数据源。需要把原始的数据结构,组织成二维数组,第一层数组用于分section,第二层数组是每个section中的元素。主要代码如下(清晰起见,省略无关代码):

每一行的数据结构:

@interface Member : NSObject

@property(nonatomic,copy) NSString *pk;
@property(nonatomic,copy) NSString *name;
@property NSInteger sectionNumber;

@end

首先是从数据源中读取原始数据,这时还没有分组:

NSMutableArray *membersTemp = [NSMutableArray array];

while(){
    Member *member = [[Member alloc] initWithPk:pk Name:name];
    [membersTemp addObject:member];
}

然后给每个Memer分配SectionNumber,这里用到了UILocalizedIndexedCollation类,不需要自己处理索引分组。网上很多例子都用到外部的分组方法,其实是不需要的:

UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation];
    
for(Member *member in membersTemp) {
    NSInteger sect = [collation sectionForObject:member collationStringSelector:@selector(name)];
    member.sectionNumber = sect;
}

然后创建了27个数组,分别是A-Z和#的索引,数组只是初始化,还没有把Member放进去:

NSInteger highSection = [[collation sectionTitles] count];
NSMutableArray *sectionArrays = [NSMutableArray arrayWithCapacity:highSection];
for(int i = 0; i < highSection; i++) {
    NSMutableArray *sectionArray = [NSMutableArray arrayWithCapacity:1];
    [sectionArrays addObject:sectionArray];
}

然后把Member放入合适的数组:

for(Member *member in membersTemp) {
    [(NSMutableArray*)[sectionArrays objectAtIndex:member.sectionNumber] addObject:member];
}

最后,把数组排序,放到真正的members里,这样members就是一个二维数组:

for(NSMutableArray *sectionArray in sectionArrays) {
    NSArray *sortedSection = [collation sortedArrayFromArray:sectionArray collationStringSelector:@selector(name)];
    [members addObject:sortedSection];
}

经过上面的代码,members就是已经组织好的二维数组。接下来要实现TableViewDataSource的代理方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [members count];// 多少个section
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[members objectAtIndex:section] count];// section的row数,会调用多次
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:[UITableViewCell reuseIdentifier]];
    if(!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[UITableViewCell reuseIdentifier]];
    }
    
    Member *member = [[members objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];// 每一行
    cell.textLabel.text = member.name;
    return cell;
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];// A-Z, #
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
     
    if ([[members objectAtIndex:section] count] > 0) {
        return [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];// 空的数组,没有title
    }
    return nil;
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];// 点击索引导航
}

关于这个问题,官方文档比网上任何文档都清楚

分享到:
评论

相关推荐

    UITableView汽车名牌带右侧索引

    UITableView汽车名牌带右侧索引,主要实现右侧索引功能

    iOS UITableView分组示例

    实现了简单的分组tableView,显示的是省份-城市关联信息,测试数据使用plist属性文件保存。...另外实现了类似iPhone通讯录根据字母快速索引联系人的功能,这里是点击右侧的省份名称,快速定位到其下辖的城市列表。

    iphone通讯录的简单实现

    用UITableView实现我的通讯录的功能,包括索引功能、名字的头字母的排序等,搜索功能还没实现。

    swift-TableView分区索引回调

    UITableView内部的UITableViewIndex,实现滑动事件的监听回调

    CoreData_CONTACT-INDEXING-PHONE-TABLEVIEW-Under_WorldFactsFolder

    我认为他们实现索引的想法非常棒,它是优秀用户体验的最佳例子之一。 我希望更多的应用程序将使用类似的索引而不是通用的索引。 优酷视频 示例代码 @interface MJNIndexTestViewController () @property ( ...

    MJNIndexView:MJNIndexView

    我认为他们实现索引的想法非常出色,它是出色的UX的最好例证之一。 我希望更多的应用程序将使用相似的索引,而不是通用的索引。YouTube视频范例程式码@interface MJNIndexTestViewController () ...

    iOS开发中TabBar再次点击实现刷新效果

    现在需要实现一个类似今日头条TabBar的功能 —— 如果继续点击当前TabBar的选中项,那么该界面需要刷新UITableView。 分析 既然已经自定义了TabBar,那么最简单的就是在自定义中给TabBar中需要的UITabBarButton添加...

    FunctionalTableData:声明式UITableViewDataSource实现

    功能表数据为UITableView实现功能渲染器。 您将表状态的完整描述传递给它,然后“功能表数据”将其与先前的render调用进行比较,以插入,更新和删除已更改的节和单元格。 这极大地简化了复杂UI的状态管理。 您不再...

    DHCollectionTableView:带有Swift的UITableView中的UICollectionView

    用Swift实现UITableView内嵌UICollectionView的效果如下: 不用担心每个item的索引获取 如何使用 // source就是要显示的数据,图片什么的,随意啦, format: Array&lt;Array&gt;&gt; let viewController = ...

    ThunderTable:UITableView的声明性包装方法

    并消除了拥有较长的索引路径和if语句链的必要性。 这个怎么运作 迅雷表包含两种主要类型的对象: 行数 表格行是符合“ Row协议的对象,此协议具有诸如标题,字幕和图像之类的属性,这些属性负责将内容提供给表格...

    掌上汇.zip

    完整,工程下载可运行: 内容包括: 自定义单元格,导航视图页面切换,带索引的UITableView,单元格左右滑动动画实现,访问雅虎财经URL地址获取实时货币汇率,进行切换等。

    ios原生和react-native各种交互的示例代码

    目前RN中的ListView主要问题是复用,以及其他一些细节如索引视图、左滑删除、编辑等,要想在RN上自定义实现原生的这种效果尚有一定的问题,在必要时可以考虑使用原生的UITableView,数据从RN端传递 1、原生端编写...

    GCMAggregatingTableViewDataSource

    UITableViewDataSource 的实现,它允许将多个子 UITableViewDataSource 实现组合在一起并呈现给 UITableView,就好像它们是单个数据源一样。 在您希望单个表视图显示来自多个源的内容并且希望将这些数据源的逻辑...

    ios开发记录

    //索引为0表示先添加的子视图,跟子视图的tag没有关系 //交换两个子视图的先后位置 [self.window exchangeSubviewAtIndex:0 withSubviewAtIndex:1]; exchange交换 Subview 代替 //remove 移除 from 从 superview ...

    iPhone开发秘籍

    5.1 uitableview和uitableview-controller简介 113 5.1.1 创建表格 113 5.1.2 uitableviewcontroller的作用 115 5.2 秘诀:创建简单的列表表格 115 5.2.1 数据源函数 116 5.2.2 重用单元格 116 5.2.3 字体...

    iPhone开发秘籍.part2.rar

    5.1 UITableView 和UITableView- Controller 简介.....113 5.1.1 创建表格.....113 5.1.2 UITableViewController 的 作用.....115 5.2 秘诀:创建简单的列表表格.....115 5.2.1 数据源函数.....116 5.2.2 重用单元格...

    iPhone开发秘籍.part1.rar

    5.1 UITableView 和UITableView- Controller 简介.....113 5.1.1 创建表格.....113 5.1.2 UITableViewController 的 作用.....115 5.2 秘诀:创建简单的列表表格.....115 5.2.1 数据源函数.....116 5.2.2 重用单元格...

    iPhone开发秘籍.part4.rar

    5.1 UITableView 和UITableView- Controller 简介.....113 5.1.1 创建表格.....113 5.1.2 UITableViewController 的 作用.....115 5.2 秘诀:创建简单的列表表格.....115 5.2.1 数据源函数.....116 5.2.2 重用单元格...

Global site tag (gtag.js) - Google Analytics