2010-07-31 6 views
10

Existe-t-il un moyen de grouper/d'auto-couper automatiquement mon UITableView par ordre alphabétique? J'ai un énorme tableau qui s'affiche bien, mais ce serait encore mieux si j'avais les sections comme dans Contacts.app.Autogroupe UITableView par ordre alphabétique

Meilleur
-f

+0

Je n'ai pas trouvé un moyen d'activer le groupage automatique. Je l'ai donc implémenté moi-même en passant par les tableaux et en construisant de nouveaux basés sur les premières lettres de ses entrées. – flohei

+0

Pourriez-vous poster votre solution? Cela rendrait plus clair que ce problème a été résolu. En outre, s'il obtient trois upvotes, vous obtiendrez un badge d'auto-apprenant pour votre problème. –

+0

Oh cool. Oui, je l'afficherai demain. – flohei

Répondre

29

d'abord toutes les sections Définir

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]; 

puis

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

Après ce filtre par alphabets

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

Merci pour votre réponse. Comme cela fait un moment que je ne l'ai pas fait, je ne suis pas tout à fait sûr, mais cela me semble familier. Je pense que j'ai adopté une approche similaire. – flohei

+0

Où dois-je placer le code NSArray * sectionArray? –

+0

où vous avez besoin d'un élément pour une section particulière – yasirmturk

2

je l'ai fait ce qui suit:

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 

puis dans votre 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

J'ai un pod juste pour ce :

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

pod 'CGLAlphabetizer', '~> 0.1'

Il crée un dictionnaire de tableaux indexés par les lettres de l'alphabet à partir d'un seul tableau d'objets et un KeyPath arbitraire.

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

Donc, en supposant que vous aviez l'objet de modèle qui ressemblait à ceci:

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

@property (nonatomic, readonly) NSString *fullName; 

@end 

Votre implémentation tableViewController pourrait ressembler à ceci:

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 

Equipées tous les êtres humains qui est allé à l'espace:

demo

Questions connexes