方案A:基本型,按步就班完成各个实现,就可以实现带索引功能的tableview了,最佳参考就是apple自带的sample code
==== ====
下面的代码就启动了view,继承自uitableviewcontroller
rootViewController.timeZonesArray = timeZones; //有定义 //- (void)setTimeZonesArray:(NSMutableArray *)newDataArray { //setter代码会被执行 // Configure and display the window. [window addSubview:[navigationController view]]; [window makeKeyAndVisible];setter所进行的工作,典型判断,是否一致,需要变化(如果内容是新的,而且不是空的,开始根据采用的UILocalizedIndexedCollation sectiontitles来构造分组过的tableview数据源,这点很重要,如何构造这个数据源,根据什么原则,比如首字母,最后一个字母等等方式,多可以在这个configursections中控制):
- (void)setTimeZonesArray:(NSMutableArray *)newDataArray { if (newDataArray != timeZonesArray) { [timeZonesArray release]; timeZonesArray = [newDataArray retain]; //ARC will automatically give retain... } if (timeZonesArray == nil) { self.sectionsArray = nil; } else { // 不是空的数组时候,需要配置下sections根据collation [self configureSections]; } }最简单的方式,就是没有复杂的分组判断抽取函数,依赖单一的属性或自身的情况:
- (void)configureSections {
这个似乎比较基本,均得到26字母再加#
self.collation = [UILocalizedIndexedCollation currentCollation];
//Returns the list of section titles for the table view.... .... 27=26+1
NSInteger index, sectionTitlesCount = [[collation sectionTitles] count];
//tableView 会被分成27个section
NSMutableArray *newSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
//产生section的数组,根据大小。。。 。。。 // Set up the sections array: elements are mutable arrays that will contain the time zones for that section. // seperated sections...给每个section下增加一个数组对象。。 for (index = 0; index < sectionTitlesCount; index++) { NSMutableArray *array = [[NSMutableArray alloc] init]; [newSectionsArray addObject:array]; [array release]; } // Segregate the time zones into the appropriate arrays. for (TimeZoneWrapper *timeZone in timeZonesArray) { // Ask the collation which section number the time zone belongs in, based on its locale name. NSInteger sectionNumber = [collation sectionForObject:timeZone collationStringSelector:@selector(localeName)]; //根据属性localname给出timeZone的位置 ... ... // Get the array for the section. 获得 NSMutableArray *sectionTimeZones = [newSectionsArray objectAtIndex:sectionNumber]; // Add the time zone to the section. [sectionTimeZones addObject:timeZone]; } //可以没有,局部排序。。。完全看实际情况 // Now that all the data's in place, each section array needs to be sorted. for (index = 0; index < sectionTitlesCount; index++) { NSMutableArray *timeZonesArrayForSection = [newSectionsArray objectAtIndex:index]; // If the table view or its contents were editable, you would make a mutable copy here. //Sorts the objects within a section by their localized titles. NSArray *sortedTimeZonesArrayForSection = [collation sortedArrayFromArray:timeZonesArrayForSection collationStringSelector:@selector(localeName)]; // Replace the existing array with the sorted array. [newSectionsArray replaceObjectAtIndex:index withObject:sortedTimeZonesArrayForSection]; } self.sectionsArray = newSectionsArray; [newSectionsArray release]; }这里带来疑问,假如我们已有一个分组的大数组,那么是否还需要构造一次呢,目前来看,还要调整,因为你要匹配索引对应的 index,比如说,那个数组就应是27个元素的(每个element=section)。
还有一个就是section title是可以自己组合的 。
接下来,是几个标准的方法:根据点击的index的某个项目,可以获得title以及index,然后自动scroll到一个位置。
sectionForSectionIndexTitleAtIndex:index of UILocalizedIndexedCollation
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { //Returns the section that the table view should scroll to for the given index title. return [collation sectionForSectionIndexTitleAtIndex:index]; }通过下面的方法就关联了所显示的indextitles和tableview的关系。在这个地方
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return [collation sectionIndexTitles]; }在这里,可以把内容进行替换,例如显示符号而不是字母等方式:
sectionIndexTitlesForTableView
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { for(id item in [collation sectionIndexTitles] ) NSLog(@"the titles: %@",item); //SimpleIndexedTableView[908:f803] the titles: #
return [collation sectionIndexTitles];
解下来就是一些常规的tableview的函数了,和普通的用法一致
titleForHeaderInSection
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection
- (NSInteger)numberOfSectionsInTableView
//Returns an integer identifying the section in which a model object belongs. - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return [[collation sectionTitles] objectAtIndex:section]; }那么我们就要看看怎么定制化?
1. 数据已具备,那么可以通过编列collation的sectiontitles时候,处理一下,把现有数据对应到根据collation构造的datasource。
self.collation = [UILocalizedIndexedCollation currentCollation]; //Returns the list of section titles for the table view.... .... 27=26+1 NSInteger index, sectionTitlesCount = [[collation sectionTitles] count]; NSLog(@"the total number: %d",sectionTitlesCount); NSMutableArray *newSectionsArray=[[NSMutableArray alloc] initWithCapacity:sectionTitlesCount]; //产生section的数组,根据大小。。。 。。。 // Set up the sections array: elements are mutable arrays that will contain the time zones for that section. // seperated sections...给每个section下增加一个数组对象。。 for (index = 0; index < sectionTitlesCount; index++) { NSLog(@"%@", [[collation sectionTitles] objectAtIndex:index]); switch (index) { case 0: { NSArray *group1=[[NSArray alloc] initWithObjects:@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",@"aaaa",@"abce",nil]; [newSectionsArray addObject:group1]; break;} case 1: { NSArray *group2=[[NSArray alloc] initWithObjects:@"bccc",nil]; [newSectionsArray addObject:group2]; break; }
2. 移出没有子数据的section,这点怎么处理?
保证section的数目是正确的;保证section header显示内容是对的;section下面的子内容是对的;sectionForSectionIndexTitleAtIndex是能正常工作的
2.1删除其它空的子数组,保证section的数目是对的!
2.2而 section header,简单一点就是:
NSString* object = [[sectionsArray objectAtIndex:section] objectAtIndex:0]; const char* objectChar = [object UTF8String]; return [[[NSString alloc] initWithFormat:@"%c", objectChar[0]] autorelease];通过拿出对象的首字母,反向显示出来,而不是之前的,通过sectiontitles来获得
[[collation sectionTitles] objectAtIndex:section];2.3 section下面的子内容是对的,这个没有问题的,因为现在的数据源是对的。
2.4保证能正确索引:
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { //return [collation sectionForSectionIndexTitleAtIndex:index]; 原标准代码,仅使用到这个index // treat the last index (#) separatelly because NSString compare: thinks it's lower than any letter and will cause wrong results if ([title isEqualToString:@"#"]) return [sectionsArray count] - 1; // go through the sections and return the first one that matches the title or is AFTER it. // If none is found, return the previous one int nLastBefore = 0; NSComparisonResult compareResult; for (int i=0; i<[sectionsArray count]; i++) { NSString* sectionTitle = [self tableView:tableView titleForHeaderInSection:i]; compareResult = [[sectionTitle uppercaseString] compare:title]; NSLog(@"%@",[sectionTitle uppercaseString]);//随程序决定,大小写在比较时候重要 if (compareResult == NSOrderedSame || compareResult == NSOrderedDescending) return i; nLastBefore = i; }// for i return nLastBefore; }
|
但是还会有问题:怎么把这个UI表现(sectiotitle)自定义呢。看看contacts的图:
The titles of the sections in that code come from the UILocalizedIndexedCollation object. If you want to have your own section titles that's fine. You still need to build a sectioned data model.If you don't want the index on the right side then the collation object probably isn't much help to you. Regardless, that code builds a sectioned data model, which you also need if you want a sectioned table view.
还会有问题的,如果我们组合了searchbar在这个tableview会如何?如果使用uitableview动态而不是来自uitableviewcontroller会如何?
在使用