給 TableView 加索引的方法不必多說,但有的 TableView 會顯示其指向內(nèi)容為空的索引,如官方自帶的通訊錄這樣:

C、D、E等字母所指向的聯(lián)系人為空,但是也顯示了出來
所謂的非空索引指的是當索引所指向的 section 內(nèi)容為空時,不添加這條索引,如圖:

當這個字母所指向的省份為空時,自動不顯示
話不多說,上代碼:
省份的模型:
@interface State : NSObject
@property(nonatomic,copy) NSString *name;
@property NSInteger sectionNumber;
@end
加載 plist 中的內(nèi)容,將其轉(zhuǎn)換為一個二維數(shù)組,并在其中用官方的 UILocalizedIndexedCollation 將數(shù)組按拼音的字母順序排序,這里只添加不為空的數(shù)組,保證索引都不為空。
- (NSMutableArray *)states
{
if (_states == nil) {
_states = [NSMutableArray arrayWithCapacity:1];
NSString *thePath = [[NSBundle mainBundle] pathForResource:@"ProvincesAndCities" ofType:@"plist"];
NSArray *tempArray;
NSMutableArray *statesTemp;
if (thePath && (tempArray = [NSArray arrayWithContentsOfFile:thePath])) {
statesTemp = [NSMutableArray arrayWithCapacity:1];
for (NSDictionary *stateDict in tempArray) {
State *aState = [[State alloc] init];
aState.name = [stateDict objectForKey:@"State"];
[statesTemp addObject:aState];
}
}else{
return nil;
}
UILocalizedIndexedCollation *theCollation = [UILocalizedIndexedCollation currentCollation];
//1. 將 state 按其屬性 name 的拼音順序排序
for (State *theState in statesTemp) {
NSInteger sect = [theCollation sectionForObject:theState collationStringSelector:@selector(name)];
theState.sectionNumber = sect;
}
//2. 創(chuàng)建一個二維數(shù)組
NSInteger highSection = [[theCollation sectionTitles] count];
NSMutableArray *sectionArrays = [NSMutableArray arrayWithCapacity:highSection];
for (int i = 0; i < highSection; i++) {
NSMutableArray *sectionArray = [NSMutableArray arrayWithCapacity:1];
[sectionArrays addObject:sectionArray];
}
//3. 將 state 按序號加入組中
for (State *theState in statesTemp) {
[(NSMutableArray *)[sectionArrays objectAtIndex:theState.sectionNumber] addObject:theState];
}
//4. 組內(nèi)排序
for (NSMutableArray *sectionArray in sectionArrays) {
if ([sectionArray count] > 0) {
NSArray *sortedSection = [theCollation sortedArrayFromArray:sectionArray
collationStringSelector:@selector(name)];
[_states addObject:sortedSection];
}
}
}
return _states;
}
UILocalizedIndexedCollation 默認從0開始,指向從A到Z的數(shù)據(jù),之前刪除掉了為空的字母,這里需要重新將字母順序與字母對應起來。
- (NSMutableArray *)letterArray
{
if (_letterArray == nil) {
_letterArray = [NSMutableArray arrayWithCapacity:[self.states count]];
NSArray *letterArr = @[@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",
@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",
@"U",@"V",@"W",@"X",@"Y",@"Z"];
for (NSMutableArray *array in self.states) {
if ([array count] > 0) {
State *tmpState = array[0];
[_letterArray addObject:[letterArr objectAtIndex:tmpState.sectionNumber]];
}
}
}
return _letterArray;
}
TableView 的代理方法:
//返回索引數(shù)組
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return self.letterArray;
}
//當點擊索引時,跳轉(zhuǎn)到對應的section
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
//返回 section 標題
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.letterArray objectAtIndex:section];
}