codebot
codebot

Reputation: 2646

How to make up an array with objects for title index uitableview iOS?

I'm making a title indexed event invitation list. I have an array with EventStatus objects. I'm making the _data array for table like,

for (int i = 0; i < eventStatusList.count; i++) {
    NSString *firstName = ((OCEventStatus*)eventStatusList[i]).user.firstName;
    [_sortedUsers setObject:((OCEventStatus*)eventStatusList[i]).user.firstName forKey:[firstName substringToIndex:1]];
}
_sortedUserTitles = [[[_sortedUsers allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)] mutableCopy];

_data = [eventStatusList mutableCopy];
[self.dataTableView reloadData];

and I think this for loop thing is too slow. Is there a way to do this in a good manner? Following is the title index making up logic with UITablrViewDataSource methods.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [_sortedUserTitles count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    NSString *sectionTitle = [_sortedUserTitles objectAtIndex:section];
    NSArray *sectionUsers = [_sortedUsers objectForKey:sectionTitle];
    return [sectionUsers count];

}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    //  return animalSectionTitles;
    return _alphabetArray;
}

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

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

This is error because of in the _sortedUsers dictionary has a string instead of an array. How may I fix this? And also please suggest a fast, good manner to implement this title index.

Upvotes: 1

Views: 146

Answers (1)

Gulliva
Gulliva

Reputation: 488

If you want to create an List of Firstnames try this perhaps.

At interface:

@property(nonatomic, strong)NSMutableDictionary *dict;
@property(nonatomic, strong)NSMutableArray *alphabet;

_dict = [NSMutableDictionary new];
_alphabet = [NSMutableArray new];
[eventStatusList sortUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
    OCEventStatus *ev1 = (OCEventStatus*)obj1;
    OCEventStatus *ev2 = (OCEventStatus*)obj2;
    return [ev1.firstName compare:ev2.firstName];
}];

for(OCEventStatus *state in eventStatusList){
    NSString *firstchar = [[state.firstName substringToIndex:1] lowercaseString];
    if([dict objectForKey:firstchar]==nil){
         NSMutableArray *tmp = [NSMutableArray new];
        [tmp addObject:state];
        [_dict setObject:tmp forKey:firstchar];
        [_alphabet addObject:firstChar];
    }else{
        [[dict objectForKey:firstchar] addObject:state];
    }
}

Now you have an Array of firstnames in a Dictionary which has the first letter as the key for Example: a -> ["Alfred","Albert",...]

In the Datasource methods you have to return it like this...

-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{
 return dict.count;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection;(NSInteger)section
{
    return [dict objectForKey:[alphabet objectAtIndex:section]].count;
}

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
OVEventStatus *state =  [[dict objectForKey:[alphabet objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.text = state.firstName;
    return cell;

}

Please try if this fits for you

Update:

If you also want to Sort the Arrays I would recommend to sort the eventListBy firstName first! So you have the correct order when you loop over the eventStatusList.

Upvotes: 3

Related Questions