Фильтрация секционных UITableView - PullRequest
0 голосов
/ 03 мая 2011

Мое приложение имеет пользовательский интерфейс, аналогичный Phone.app-> Recents: секционированный UITableView и UISegmentedControl на панели навигации. Что я хочу сделать, это отобразить полный набор данных, если выбран первый раздел, и отобразить отфильтрованный набор данных, если выбран второй раздел.

Когда пользователь выбирает второй элемент в UISegmentedControl, я удаляю определенные строки из табличного представления. Вот код:

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

Приведенный выше код работает нормально, за исключением одной серьезной проблемы: производительности. Удаление 1500 из 2200 строк занимает около 20 секунд. Это явно недопустимо. Каков наилучший подход к фильтрации строк табличного представления с анимацией?

Ответы [ 3 ]

1 голос
/ 03 мая 2011

Для больших изменений в вашем источнике данных рекомендуется использовать

[tableView reloadData]

вместо

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

РЕДАКТИРОВАТЬ: Я сам не пробовал этот подход, но рассмотрите возможность изменения только тех строк, которые содержатся в наборе видимых ячеек, возможно, с буфером выше и ниже. Вы можете получить indexPaths видимых ячеек, вызвав

[tableView indexPathsForVisibleRows];
0 голосов
/ 04 августа 2012

Я определенно согласен с @nduplessis в том, что вам следует перезагрузить источник данных, а не манипулировать представлением.Я предложил решение для подобного вопроса здесь , которое действительно заставило бы ваши строки скользить вверх.

Основная идея - вызвать reloadSections: withRowAnimation: и в ваших методах UITableViewDataSource включить сегментированныйcontrolS 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...
}
0 голосов
/ 03 мая 2011

Как насчет использования двух массивов?Одним из них является полный набор данных, а другим - отфильтрованный набор данных.

Таким образом, вы можете иметь два разных табличных представления, и в зависимости от того, что представляет собой выбранный сегмент, вы можете сделать анимацию затухания между двумяtableviews.Например, допустим, вы выбрали сегмент:

-(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, чтобы проверить, какое представление таблицы устанавливается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...