[ios] 아이폰 UITableView. 음악 앱과 같은 단일 문자 알파벳 목록을 어떻게 켜나요?

iPhone 음악 앱에서 아티스트, 노래 또는 앨범을 선택하면 UI 오른쪽에 단일 문자의 정점 목록이있는 tableView가 표시되어 빠르게 스크롤 할 수 있습니다. 내 앱에서이 기능을 어떻게 활성화합니까?

건배, 더그



답변

고유 한 색인 문자를 제공하십시오.

- (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 개의 섹션이 있기 때문에) 배열에서 특정 문자로 시작하는 첫 번째 항목의 위치에 대한 인덱스를 계산 한 다음 스크롤합니다. 그것에.

단점은 매번 배열을 검색해야한다는 것입니다 (이것이 절대적으로 끔찍합니까?).하지만 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;
}

마지막으로 선택한 색인을 저장할 속성 추가

 @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에 값을 반환하지 않는 해결책을 찾았지만 모퉁이에 있고 알파벳의 모든 문자에 대해 섹션을 만들 필요가 없다면 확실한 수정입니다. 사전에 코드 나치에게 죄송합니다. :피

- (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설명서를 참조하십시오.