2010-07-31 9 views
10

Gibt es eine Möglichkeit, meine UITableView alphabetisch zu gruppieren/automatisch zu teilen? Ich habe ein riesiges Array, das schön angezeigt wird, aber es wäre noch besser, wenn ich die Abschnitte wie in Contacts.app hätte.Autogroup UITableView alphabetisch

Beste
-f

+0

Ich habe keine Möglichkeit gefunden, die automatische Gruppierung zu aktivieren. Also implementierte ich es selbst, indem ich die Arrays durchblätterte und basierend auf den Anfangsbuchstaben der Einträge neue erstellte. – flohei

+0

Können Sie Ihre Lösung posten? Das würde deutlicher machen, dass dieses Problem gelöst wurde. Wenn es drei Upvotes bekommt, bekommst du ein Selbstlerner-Abzeichen für deine Probleme. –

+0

Oh cool. Ja, ich werde es morgen posten. – flohei

Antwort

29

Zu allererst definieren Abschnitte

self.sections = [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]; 

dann

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 27; 
} 

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 
{ 
    return self.sections; 
}  

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

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    return [self.sections objectAtIndex:section]; 
} 

Nach diesem Filter durch Alphabete

NSArray *sectionArray = [vendorList filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF beginswith[c] %@", [self.sections objectAtIndex:section]]]; 
      rowCount = [sectionArray count]; 
+0

Danke für Ihre Antwort. Da es eine Weile her ist, seit ich das getan habe, bin ich mir nicht ganz sicher, aber das kommt mir bekannt vor. Ich denke, ich habe einen ähnlichen Ansatz gewählt. – flohei

+0

Wo lege ich den NSArray * sectionArray Code? –

+0

wo immer Sie brauchen, um Artikel für einen bestimmten Abschnitt zu erhalten – yasirmturk

2

ich habe folgendes:

AutoSectionTableViewDataSource.h

@protocol AutoSectionTableViewDataSource 
- (NSString*)tableView:(UITableView*)tableView sectionNameAtIndexPath:(NSIndexPath*)indexPath; 
@end 
@interface AutoSectionTableViewDataSource : NSObject <UITableViewDataSource> 
- (id)initWithDataSource:(NSObject<UITableViewDataSource,AutoSectionTableViewDataSource>*)dataSource; 
@end 

AutoSectionTableViewDataSource.m

@interface AutoSectionTableViewDataSource() 
@property(weak) NSObject<UITableViewDataSource,AutoSectionTableViewDataSource> *dataSource; 
@end 
@implementation AutoSectionTableViewDataSource 

- (id)initWithDataSource:(NSObject<UITableViewDataSource,AutoSectionTableViewDataSource>*)dataSource 
{ 
    self = [super init]; 
    self.dataSource = dataSource; 
    return self; 
} 

- (BOOL)respondsToSelector:(SEL)selector 
{ 
    if ([super respondsToSelector:selector]) return YES; 
    if (self.dataSource && [self.dataSource respondsToSelector:selector]) return YES; 
    return NO; 
} 

- (void)forwardInvocation:(NSInvocation*)invocation 
{ 
    if (self.dataSource && [self.dataSource respondsToSelector:invocation.selector]) { 
     [invocation invokeWithTarget:self.dataSource]; 
    } else { 
     [self doesNotRecognizeSelector:invocation.selector]; 
    } 
} 

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector 
{ 
    if (self.dataSource) return [self.dataSource methodSignatureForSelector:selector]; 
    return nil; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0]; 
    NSMutableSet *set = [[NSMutableSet alloc] init]; 
    for (NSInteger row=0; row<rows; row++) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0]; 
     NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:indexPath]; 
     [set addObject:sectionName]; 
    } 
    return set.count; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0]; 
    NSMutableDictionary *tmp = [[NSMutableDictionary alloc] init]; 
    NSInteger count = 0; 
    for (NSInteger row=0; row<rows; row++) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0]; 
     NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:indexPath]; 
     if (!tmp[sectionName]) { 
      tmp[sectionName] = @(tmp.count); 
     } 
     if ([tmp[sectionName] intValue] == section) { 
      count++; 
     } 
    } 
    return count; 
} 

- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{ 
    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0]; 
    NSMutableSet *set = [[NSMutableSet alloc] init]; 
    for (NSInteger row=0; row<rows; row++) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0]; 
     NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:indexPath]; 
     if (![set containsObject:sectionName]) { 
      [set addObject:sectionName]; 
      if (set.count - 1 == section) { 
       //NSLog(@"AutoSectionTableViewDataSource titleForHeaderInSection:%d -> %@", section, sectionName); 
       return sectionName; 
      } 
     } 
    } 
    return nil; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSInteger rows = [self.dataSource tableView:tableView numberOfRowsInSection:0]; 
    NSMutableDictionary *tmp = [[NSMutableDictionary alloc] init]; 
    NSInteger count = 0; 
    for (NSInteger row=0; row<rows; row++) { 
     NSIndexPath *rowIndexPath = [NSIndexPath indexPathForRow:row inSection:0]; 
     NSString* sectionName = [self.dataSource tableView:tableView sectionNameAtIndexPath:rowIndexPath]; 
     if (!tmp[sectionName]) { 
      tmp[sectionName] = @(tmp.count); 
     } 
     if ([tmp[sectionName] intValue] == indexPath.section) { 
      count++; 
      if (count-1 == indexPath.row) { 
       UITableViewCell *cell = [self.dataSource tableView:tableView cellForRowAtIndexPath:rowIndexPath]; 
       return cell; 
      } 
     } 
    } 
    return nil; 
} 

@end 

und dann in Ihrem Code:

- (NSString*)tableView:(UITableView *)tableView sectionNameAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return @"this would be your section name for indexPath.row" 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return total_number_of_rows; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return cell_for_indexPath.row; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // instead of self.tableView.dataSource = self; use: 
    self.autoSectionDataSource = [[AutoSectionTableViewDataSource alloc] initWithDataSource:self]; 
    self.tableView.dataSource = self.autoSectionDataSource; 
} 
4

Ich habe eine pod nur für diese :

https://github.com/chrisladd/CGLAlphabetizer/

pod 'CGLAlphabetizer', '~> 0.1'

Es schafft ein Wörterbuch von Arrays von Buchstaben des Alphabets aus einem einzelnen Array von Objekten und einer beliebigen keyPath verkeilt.

alphabetizedDictionary = [CGLAlphabetizer alphabetizedDictionaryFromObjects:anArray usingKeyPath:@"keyPath"];

Also, Sie unter der Annahme, hatte das Modell Objekt, das so aussah:

@interface CGLContact : NSObject 
@property (nonatomic) NSString *firstName; 
@property (nonatomic) NSString *lastName; 

@property (nonatomic, readonly) NSString *fullName; 

@end 

Ihre Tableviewcontroller Implementierung wie folgt aussehen könnte:

static NSString * const CGLContactsCellIdentifier = @"CGLContactsCellIdentifier"; 

@interface CGLContactsTableViewController() 
@property (nonatomic) NSDictionary *alphabetizedDictionary; 
@property (nonatomic) NSArray *sectionIndexTitles; 
@end 

@implementation CGLContactsTableViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CGLContactsCellIdentifier]; 
} 

- (void)setContacts:(NSArray *)contacts { 
    _contacts = contacts; 
    self.alphabetizedDictionary = [CGLAlphabetizer alphabetizedDictionaryFromObjects:_contacts usingKeyPath:@"lastName"]; 
    self.sectionIndexTitles = [CGLAlphabetizer indexTitlesFromAlphabetizedDictionary:self.alphabetizedDictionary]; 

    [self.tableView reloadData]; 
} 

- (CGLContact *)objectAtIndexPath:(NSIndexPath *)indexPath { 
    NSString *sectionIndexTitle = self.sectionIndexTitles[indexPath.section]; 
    return self.alphabetizedDictionary[sectionIndexTitle][indexPath.row]; 
} 

#pragma mark - Table view data source 

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 
    return self.sectionIndexTitles; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return [self.sectionIndexTitles count]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    NSString *sectionIndexTitle = self.sectionIndexTitles[section]; 
    return [self.alphabetizedDictionary[sectionIndexTitle] count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CGLContactsCellIdentifier forIndexPath:indexPath]; 

    CGLContact *contact = [self objectAtIndexPath:indexPath]; 
    cell.textLabel.text = contact.fullName; 

    return cell; 
} 

@end 

Bestückt mit jedem Menschen, der ist ins Weltall gegangen:

demo