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/uilocalizedindexedcollation
我提出了另一种方法来处理单个字母的字母表,而不使用章节。 这与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应用程序的提示。 🙂