Wednesday, March 21, 2012

Handling multiple selection in iPhone TableView

- Rashid Khaleefa
Its a common practice to list down the data or items in any mobile phone. The display of contact list is a very common example in any mobile phone where you see a list of contacts saved. Even though the brand, the OS or the model differs, when it comes to bulk of data to display either a listview control or any tableview alternative controls are used.
In iPhone items can be displayed using the UITableview control. I came across using this control in my iPhone app. It was quiet easy to get started with displaying a list of data from an array. I just had to use the UITableview control along with its delegates to handle the display. It is much cool to use three functions as below to display the items. Here I have an array of dictionaries to list out in the tableview.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//Return the number of rows in the section.
return [tableList count];
}

And cellForRowAtIndexPath function gets called once for each row. This is where we define what content to display in a given row or cell. We assign the values to each cell labels. I have used a custom cell designed with three labels and an imageview separately and values are assigned to the corresponding controls in each cell.

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *CellID = @"CustomCell";
 CustomCellController *cell = (CustomCellController*)[tableView  
 dequeueReusableCellWithIdentifier:CellID];
 if (cell == nil)
 {
  NSArray *topLevelObjects = [[NSBundle mainBundle]   
  loadNibNamed:@"CustomCellController" owner:nil options:nil];
 for(id currentObject in topLevelObjects)
 {
  if([currentObject isKindOfClass:[CustomCellController class]])
  {
  cell = (CustomCellController *)currentObject;
  break;
  }
 }
}
//tableList is an array on dictionary elements.
NSDictionary *item = (NSDictionary *)[tableList objectAtIndex:indexPath.row];
[[[cell Name] setText:[UserUtils convertSize:[item objectForKey:@"ImageName"]]];
[[cell Size] setText:[item objectForKey:@"Size"]];
[[cell Date] setText:[item objectForKey:@"Date"]];
[[cell imageView] setImage:[UIImage imageNamed:@"image.png"]];
return cell;
}

But I was stuck when it came to select multiple items from the table. I quiet easily managed to select a singe item from the list using the didSelectRowAtIndexPath function. But When it came to multiple selection I started breaking my head over. This made me google and got some solutions. But never stopped me googling more because most of the solution worked fine when there was only a page of data to display, where for me it was a list of twenty items.

The first thing I had to do was to select and deselect items in table which was identifiable by a check mark indication over the selected cell. Then I wanted to retrieve the corresponding dictionary of the selected items.
The issue I faced trying to select multiple items was that when I select fist item in the table of a particular page, the corresponding first item of all page was selected and so I was not able to differentiate the item list that was actually selected. And also to select and unselect multiple items from table took me some time to work it fine.

This is how I came up with the solution

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 NSMutableDictionary *rowDict = [tableList objectAtIndex:  
 [indexPath row]];
 NSString *SelectedState = (NSString*)[rowDict 
 objectForKey:@"objSelected"];
 if([SelectedState isEqualToString: @"YES"])
 {
  [rowDict setObject:@"NO" forKey:@"objSelected"];
  [tableView cellForRowAtIndexPath:indexPath].accessoryType
  UITableViewCellAccessoryNone;
 }
 else
 {
  [rowDict setObject:@"YES" forKey:@"objSelected"];
  [tableView cellForRowAtIndexPath:indexPath].accessoryType
  UITableViewCellAccessoryCheckmark;
 }
 [tableView reloadData];
 [tableView setNeedsDisplay];
}

- (void)tableView:(UITableView *)tableView willDisplayCell:   
  (UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath
  *)indexPath
{
 NSDictionary *item = (NSDictionary *)[tableList  
 objectAtIndex:indexPath.row];
 NSString *SelectedState = (NSString*)[item 
 objectForKey:@"objSelected"];
 if([SelectedState isEqualToString: @"YES"])
 cell.accessoryType = UITableViewCellAccessoryCheckmark;
 else
 cell.accessoryType = UITableViewCellAccessoryNone;
}

Here, in didSelectRowAtIndexPath I have first retrieved the dictionary values at the particular index of selection and add one more value based on selection (YES when selected and NO when deselected) for key objectSelected and thereby placing a check mark by setting the cell accessoryType to UITableViewCellAccessoryCheckmark. This will obviously reflect the tablelist array as it is declared globally. So to make it simple the refreshed tablelist will have an additional key value pair which differentiates the selected items from the deselected one.

There will be n number of solutions for any issue of this kind. I would say this is also a way how I fixed the issue I faced. I hope this might be a useful post for any one working with UITableview in iPhone.


10 comments:

hard drive data recovery cost said...

Every phone have different features rely on manufacturer and brand, OS also depend upon it. It is nice share , i will refer it to my friend to examine it that what can be done with it.

Anonymous said...

Do you have working sample code?

Richard Majece said...

What about writing high quality academic paper? I know that bibliography means a lot in this case and you should learn more about it.

lennontilly said...

Logo Craving is the answer. Since 2001 our team has been developing logos and branding businesses. We've designed a method to ensure that each client receives exactly what they need when working with me. If it's a brand affordable web design services or rebranding We're here to make sure that everything runs smoothly from beginning to finish. People will assume your business is cheap if your logo looks cheap. A well-designed logo can create trust and brand recognition. Professional logos make you appear more established and professional. Our logo design services are affordable and can be completed in a matter of days.

Anonymous said...

샌즈카지노(예스카지노) - 【카지노사이트】바카라사이트,온라인카지노,우리카지노

Darren Demers said...

There will be n number of solutions for any issue of this kind. I would say this is also a way how I fixed the issue I faced. I hope this might be a useful post for any one working with UITableview in iPhone.
feather and down duvet king size ,
teal king size comforter set ,

David Jack said...

Excellent post it is very inspiring and informative puffer jacket content good work keep it up

La Parfums said...

The right fragrance can make or break a social media influencer's personal brand. A signature smell can help to create a strong connection between their content and their brand, leaving a lasting imprint on their followers. la parfums is a great place to find top perfumes, perfect for influencers on social media who want to stand out.

Groupbuzz said...

We understand that facing a foreclosure sale can be a terrifying experience. Our staff is dedicated to providing comprehensive assistance and knowledgeable guidance to help you navigate this tough process. We provide specialist solutions, ranging from loan modifications to alternative exit strategies, with a commitment to your financial well-being, guaranteeing you have a brighter future after foreclosure. Trust groupbuzz to assist you in deciding the right course of action at this tough time.

Chroniclecoffee said...

locally roasted coffee tend to experiment with different beans and blends, introducing customers to unique and seasonal coffee options that might not be available elsewhere. This variety keeps coffee enthusiasts excited and engaged.