开发者

Filtering sectioned UITableView

My application have UI similar to Phone.app->Recents: sectioned UITableView and a UISegmentedControl in the navigation bar. What I want to do is display full set of data if first section is 开发者_如何学Cselected and display filtered set of data if second section is selected.

When user selects second item in UISegmentedControl I delete specific rows from the table view. Here is the code:

[tableView beginUpdates];
NSMutableArray *indexPaths = [NSMutableArray array];
/// ... fill up indexPaths with row indexes
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];

The code above works fine except for one serious issue: performance. Deleting 1500 out of 2200 rows takes about 20 seconds. That is obviously unacceptable. What is the best approach to filtering table view rows with animation?


For large changes to your data source, it is recommended that you use

[tableView reloadData]

instead of

[tableView beginUpdates];
// changes here ....
[tableView endUpdates];

EDIT: I haven't tried this approach myself, but consider altering only those rows that are contained in the collection of visible cells, perhaps with a buffer above and below. You can get the indexPaths of the visible cells by calling

[tableView indexPathsForVisibleRows];


How about using a two arrays? One of them is the full data set and the other one is the filtered dataset.

This way you can have two different tableviews, and depending on what the selected segment is, you could do a fade animation between the two tableviews. For example, lets say you select a segment:

-(void)switchTableViews
{
   [UIView beginAnimations:nil context:NULL];
   [UIView setAnimationBeginsFromCurrentState:YES];
   [UIView setAnimationCurve:UIViewAnimationCurveLinear];
   [UIView setAnimationDuration:0.5];
   [UIView setAnimationDidStopSelector:@selector(hideTableView)];

   switch (segmentedControl.selectedSegmentIndex) 
   {
      case 0:
      {
         tableView1.alpha = 1.0;
         tableView2.alpha = 0.0;
      }
      break;
      case 1:
      {
         tableView1.alpha = 0.0;
         tableView2.alpha = 1.0;
      }
      break;
      default:
      break;
   }

   [UIView commitAnimations];
}

- (void)hideTableView
{
   switch (segmentedControl.selectedSegmentIndex) 
   {
      case 0:
      {
         tableView1.hidden = NO;
         tableView2.hidden = YES;
      }
      break;
      case 1:
      {
         tableView1.hidden = YES;
         tableView2.hidden = NO;
      }
      break;
      default:
      break;
   }
}

Of course, this would mean setting up different code sets for the datasource methods but it's not as difficult as you think. Just use a simple if-else to check for which tableview is being set.


I definitely agree with @nduplessis that you should reload the dataSource rather than manipulating the view. I proposed a solution to a similar question here that would indeed cause your rows to slide up.

The basic idea is to call reloadSections:withRowAnimation: and in your UITableViewDataSource methods switch on the segmented control's selectedSegmentIndex.

Assuming your data is flat (only one section) it would look something like this:

- (IBAction)segmentSwitch:(id)sender
{
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    switch (self.segmentedControl.selectedSegmentIndex)
    {
        default:
        case 0:
            return [self.allRows count];
        case 1:
            return [self.onlySomeRows count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id data;
    switch (self.segmentedControl.selectedSegmentIndex)
    {
        default:
        case 0:
            data = [self.allRows objectAtIndex:[indexPath row]];
            break;
        case 1:
            data = [self.onlySomeRows objectAtIndex:[indexPath row]];
            break;
    }

    //TODO: use data to populate and return a UITableViewCell...
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜