过滤分段UITableView

时间:2011-05-03 19:34:17

标签: iphone objective-c cocoa-touch uitableview

我的应用程序具有类似于Phone.app-> Recents的UI:导航栏中的UITableView和UISegmentedControl。我想要做的是,如果选择第一部分,则显示全部数据,如果选择第二部分,则显示已过滤的数据集。

当用户在UISegmentedControl中选择第二项时,我从表视图中删除特定行。这是代码:

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

上面的代码工作正常,除了一个严重的问题:性能。删除2200行中的1500行大约需要20秒。这显然是不可接受的。使用动画过滤表视图行的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

对于数据源的大量更改,建议您使用

[tableView reloadData]

而不是

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

编辑:我自己没有尝试过这种方法,但是考虑只更改可见单元格集合中包含的那些行,可能是上面和下面的缓冲区。您可以通过调用

来获取可见单元格的indexPath
[tableView indexPathsForVisibleRows];

答案 1 :(得分:0)

如何使用两个数组?其中一个是完整数据集,另一个是过滤数据集。

这样,您可以拥有两个不同的表视图,并且根据所选片段的内容,您可以在两个表视图之间执行淡入淡出动画。例如,假设您选择了一个细分受众群:

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

当然,这意味着为数据源方法设置不同的代码集,但这并不像您想象的那么困难。只需使用简单的if-else来检查正在设置哪个tableview。

答案 2 :(得分:0)

我绝对同意@nduplessis你应该重新加载dataSource而不是操纵视图。我提出了similar question here的解决方案,这确实会导致您的行向上滑动。

基本思想是调用reloadSections:withRowAnimation:并在你的UITableViewDataSource方法中切换分段控件的selectedSegmentIndex。

假设您的数据是平的(只有一个部分),它看起来像这样:

- (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...
}