iPhone UITableView。 如何打开音乐应用程序的单个字母按字母顺序列表?

在iPhone音乐应用程序中,select“艺术家”,“歌曲”或“专辑”会在UI的右侧显示带有单个字母的垂直列表的tableView,以实现快速滚动。 如何在我的应用程序中启用此function?

干杯,道格

提供您自己的索引字符:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return[NSArray arrayWithObjects:@"a", @"e", @"i", @"m", @"p", nil]; } 

接着:

 - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { return <yourSectionIndexForTheSectionForSectionIndexTitle >; } 

你将需要部分。

还有一些你必须考虑的是本地化每种语言的部分。 挖了一下后,我发现UILocalizedIndexedCollation非常有用:

 - (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:index]; } 

https://developer.apple.com/documentation/uikit/uilocalizedindexedcollat​​ion

我提出了另一种方法来处理单个字母的字母表,而不使用章节。 这与Zaph的答案类似,但是不是从返回一个新的索引(因为我们总是有1个部分)获得任何值,我们计算数组中以某个字符开始的第一个项目的位置的索引,然后滚动到它。

缺点是这需要每次search数组(这是绝对可怕的?),但是我没有注意到在iOS模拟器或我的iPhone 4S的任何滞后或缓慢的行为。

 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return[NSArray arrayWithObjects:@"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", nil]; } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { NSInteger newRow = [self indexForFirstChar:title inArray:self.yourStringArray]; NSIndexPath *newIndexPath = [NSIndexPath indexPathForRow:newRow inSection:0]; [tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; return index; } // Return the index for the location of the first item in an array that begins with a certain character - (NSInteger)indexForFirstChar:(NSString *)character inArray:(NSArray *)array { NSUInteger count = 0; for (NSString *str in array) { if ([str hasPrefix:character]) { return count; } count++; } return 0; } 

添加属性来存储最后select的索引

  @property (assign, nonatomic) NSInteger previousSearchIndex; 

并存储此属性每次像:

 - (NSInteger)indexForFirstChar:(NSString *)character inArray:(NSArray *)array { NSUInteger count = 0; for (NSString *str in array) { if ([str hasPrefix:character]) { self.previousSearchIndex = count; return count; } count++; } return self.previousSearchIndex; } 

并更新scrollToRow代码,如:

  [tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

做这个方法甚至更好,并有很好的animation。

一堆人问,如果没有部分就可以做到这一点。 我想要的是同样的东西,我发现一个解决scheme可能有点阴暗,不返回一个值sectionForSectionIndexTitle,但如果你在一个angular落,不想为每个字母的字母做一个部分是一个肯定的修复。 对不起,任何代码纳粹提前。 :P

 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { if (thisTableDataIsShowing) { NSMutableArray *charactersForSort = [[NSMutableArray alloc] init]; for (NSDictionary *item in d_itemsInTable) { if (![charactersForSort containsObject:[[item valueForKey:@"character_field_to_sort_by"] substringToIndex:1]]) { [charactersForSort addObject:[[item valueForKey:@"character_field_to_sort_by"] substringToIndex:1]]; } } return charactersForSort; } return nil; } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { BOOL found = NO; NSInteger b = 0; for (NSDictionary *item in d_itemsInTable) { if ([[[item valueForKey:@"character_field_to_sort_by"] substringToIndex:1] isEqualToString:title]) if (!found) { [d_yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:b inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; found = YES; } b++; } } 

如果你获得了大量的数据,并且需要大量的工作,那么它会很好用。 :)试图使用通用variables,所以你知道我在做什么。 d_itemsInTable是我列出的UITableView的NSDictionaries的NSArray。

这里是Kyle函数的一个修改版本,它可以处理单击没有string的索引的情况:

 - (NSInteger)indexForFirstChar:(NSString *)character inArray:(NSArray *)array { char testChar = [character characterAtIndex:0]; __block int retIdx = 0; __block int lastIdx = 0; [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { char firstChar = [obj characterAtIndex:0]; if (testChar == firstChar) { retIdx = idx; *stop = YES; } //if we overshot the target, just use whatever previous one was if (testChar < firstChar) { retIdx = lastIdx; *stop = YES; } lastIdx = idx; }]; return retIdx; } 

如果你使用NSFetchedResultsController ,你可以做:

 - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return [frc sectionIndexTitles]; } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { return [frc sectionForSectionIndexTitle:title atIndex:index]; } 

实现委托方法-tableView:sectionForSectionIndexTitle:atIndex:-tableView:sectionForSectionIndexTitle:atIndex:

有关更多信息,请参阅UITableViewDataSource文档。

这里有一个简单的Swift解决scheme,假设你有一个数组的标题头。 如果找不到标题,它将返回数组中的前一个索引。

 func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? { return "ABCDEFGHIJKLMNOPQRSTUVWXYZ".characters.flatMap{String($0)} } func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int { return self.headerTitles.filter{$0 <= title}.count - 1 } 

如果您使用的是MonoTouch,请覆盖UITableViewDataSource类中的SectionIndexTitles(UITableView)方法。 只需要返回一个string数组,其余的都由子类来完成。

 class TableViewDataSource : UITableViewDataSource { public override string[] SectionIndexTitles(UITableView tableView) { return new string[] { /*your string values */}; } } 

*只是为我们这些使用C#和Mono(.NET)编写iPhone应用程序的提示。 🙂