iPhoneミュージックアプリで、Artist、Songs、またはAlbumsを選択すると、UIの右側に1文字の垂直リストが表示され、高速スクロールが可能になります。アプリでこの機能を有効にするにはどうすればよいですか?
乾杯、ダグ
回答:
独自のインデックス文字を指定します。
- (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
セクションを使用せずに1文字のアルファベットリストを処理する別のアプローチを思いつきました。Zaphの回答に似ていますが、新しいインデックスを返すことで値を取得する代わりに(常に1つのセクションがあるため)、特定の文字で始まる配列内の最初のアイテムの場所のインデックスを計算してからスクロールしますそれに。
欠点は、毎回配列を検索する必要があることです(これは絶対にひどいですか?)が、iOSシミュレーターまたはiPhone4Sでの遅延や遅い動作には気づきませんでした。
- (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;
}
最後に選択したインデックスを保存するためのプロパティの追加
@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];
この方法をさらに上手く、素敵なアニメーションで実行してください。
多くの人々が、セクションなしでこれを行うことが可能かどうか尋ねました。私は同じことを望み、少し怪しげでsectionForSectionIndexTitleに値を返さない解決策を見つけましたが、あなたが隅にいて、アルファベットのすべての文字のセクションを作成する必要がない場合は、確かな修正です。事前にナチスのコードに申し訳ありません。: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++;
}
}
大量のデータを取得していて、セクショニングに多くの作業が必要な場合に最適です。:)汎用変数を使おうとしたので、私が何をしているのかがわかりました。d_itemsInTableは、UITableViewにリストしているNSDictionariesのNSArrayです。
文字列がないインデックスをクリックした場合を処理するKyleの関数の修正バージョンを次に示します。
- (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];
}
デリゲートメソッド-sectionIndexTitlesForTableView:
を実装し、-tableView:sectionForSectionIndexTitle:atIndex:
詳細については、UITableViewDataSource
ドキュメントを参照してください。
タイトルヘッダーが配列にあると仮定した場合のSwiftの簡単な解決策は次のとおりです。タイトルが見つからなかった場合は、配列内の前のインデックスが返されます。
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
}
return self.headerTitles.count - self.headerTitles.filter{$0 > title}.count
指定されたインデックスタイトルの最後の一致セクションではなく、最初のインデックスを返すように2番目の戻り行を変更することが望ましいと思います。
MonoTouchを使用している場合は、UITableViewDataSourceクラスのSectionIndexTitles(UITableView)メソッドをオーバーライドします。文字列の配列を返すだけで、残りはサブクラスが処理します。
class TableViewDataSource : UITableViewDataSource
{
public override string[] SectionIndexTitles(UITableView tableView)
{
return new string[] { /*your string values */};
}
}
* C#とMono(.NET)を使用してiPhoneアプリを作成している私たちへのヒントです。:)