Как скрыть раздел в UITableView?

В таблице есть раздел, который не содержит никаких данных и хотел бы скрыть этот раздел.

Как это сделать?

30.06.2009 00:19:41
12 ОТВЕТОВ
РЕШЕНИЕ

Вы не можете «скрыть» раздел как таковой, но вы можете «удалить» его из табличного представления, используя deleteSections:withRowAnimation:метод. Это удалит его из представления с дополнительной анимацией, не затрагивая ваши данные поддержки. (Однако вы все равно должны обновить данные, чтобы этот раздел больше не появлялся.)

Дополнительная информация: ссылка на класс UITableView

22
30.06.2009 00:47:10
Я использовал это: [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:nil]; но я получаю это сообщение: «Неверное обновление: неверное количество разделов. Количество разделов, содержащихся в табличном представлении после обновления (3), должно быть равно количеству разделов, содержащихся в табличном представлении до обновления (3), плюс или минус количество вставленных или удаленных разделов (0 вставлено, 1 Исключено). Есть идеи?
Claus 19.02.2013 16:24:13
@ Клаус: этот ответ довольно старый. Вы могли бы рассмотреть вопрос о новом вопросе . Вкратце, похоже, вам нужно обновить значение, которое вы возвращаете из -numberOfSectionsInTableView:метода источника данных. Ошибка указывает на то, что вы начинаете с трех разделов, удаляете один, а затем утверждаете, что у вас еще есть три раздела.
Tim 19.02.2013 19:16:03
Спасибо! Я нашел более простой способ установить номер строки для раздела в 0 и удалить вид заголовка раздела.
Claus 20.02.2013 15:39:52
@ Клаус Как это сделать?
zhaoyou 14.11.2016 08:26:44

Вам, вероятно, нужно удалить сам раздел из данных, которые поддерживают вашу таблицу. Я не думаю, что есть что-то, что позволяет вам просто скрыть раздел.

1
30.06.2009 00:23:38

Вы можете установить количество строк в этом разделе равным 0. Однако это оставит заметную пустую область там, где раньше была.

2
1.02.2010 23:54:14

Вы также можете вернуть количество записей, которые содержат данные из numberofSectionsInTableView: метода, и использовать метод, в switch(indexPath.section) котором пустые записи «просачиваются» к следующему переключателю, например:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    switch (indexPath.section) {
        case 0:
            return <header cell>;
            break;

        case 1:
            if(firstRecordHasData){
                return <second cell>;
                break;
            }

        case 2:
            if(secondRecordHasData){
                return <second cell>;
                break;
            }

        case 3:
            return <some other cell>;
            break;

        default:
            return <a regular cell>;
            break;
    }   
}

Некоторое время я боролся с этим, потому что мне пришлось опустить разделы в середине сгруппированной таблицы. Попытался установить высоту ячеек, верхнего и нижнего колонтитула на 0,0, но это не сработало. Не удалось просто удалить определенные разделы из-за вызванных методов в зависимости от выбранной строки. Это было бы огромным, если ... иначе, если ... еще, если бы с несколькими вызовами подпрограмм. Рад, что подумал о старом добром методе переключения, может быть, он вам тоже поможет :-)

2
13.05.2010 14:13:37
Что произойдет, если первая запись не имеет данных, а вторая запись -? Секция == 1 провалится в дело 1 и вернет ячейку дела 2. Но Раздел == 2 не будет знать, что Случай 1 провалился, и также вернет Ячейку Случая 2, когда вы захотите вернуть Ячейку Случая 3.
jamesmoschou 4.10.2011 05:50:26

На самом деле, вы можете «спрятать» раздел. Если вы хотите использовать поведение, аналогичное встроенному приложению контактов, где разделы скрыты, но все еще перечислены в индексе справа, вы можете сделать следующее:

Реализовать UITableViewDataSourceпротокол:

  • Вернуть все имена разделов (даже скрытые) в sectionIndexTitlesForTableViewметоде.

  • Для каждого пустого раздела вернитесь nilиз titleForHeaderInSectionметода.

  • Для каждой пустой секции возврата 0для numberOfRowsInSectionметода.

Я считаю, что это работает лучше, чем удаление разделов, потому что пользователь имеет последовательную навигацию по индексу.

54
15.05.2011 19:41:08
У меня не работает - «скрытые» секции по-прежнему занимают вертикальное пространство, что довольно заметно, когда их несколько. Облом, потому что это было элегантное решение!
Chris 16.08.2011 05:14:22
См. Stackoverflow.com/questions/2495936/… чтобы избавиться от стандартного расстояния между колонтитулами и колонтитулами.
smparkes 2.10.2011 22:54:48
Это идеально подходит для простой таблицы со стандартными заголовками - без проблем с пробелами.
Ben Robinson 2.02.2012 13:03:42
Это ответ, который вы ищете! :)
Daniel 27.04.2018 07:59:30
Я много экспериментировал с показом / скрытием клеток, и я также нашел это лучшее решение.
Johan Karlsson 30.01.2020 10:15:51

Я не согласен с Тимом. У нас есть способ получить доступ к любому разделу / строке таблицы из любой точки нашего кода и изменить ее свойство .hidden (и все другие свойства).

Это способ, которым я обычно пользуюсь:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:2];
[self.SeymourCakesTableView cellForRowAtIndexPath:indexPath].hidden = YES;
5
11.01.2017 00:40:57
Это работает, но проблема в том, что клетки под ним не двигаются вверх. В моем случае клетки находятся на нижнем столе, и решение хорошее.
Dr.Luiji 7.11.2012 11:00:56
Я не заметил такой проблемы. Я посмотрю, как только у меня будет время. Спасибо за указание на проблему.
Deepukjayan 9.11.2012 05:05:19

Это правда, что 0 не является допустимой высотой для верхних и нижних колонтитулов. Однако высоты являются значениями CGFloat. Вы можете указать очень маленькое число (я использовал 0,1) для высоты верхних и нижних колонтитулов.

Вроде взломать, но это работает.

14
16.04.2012 06:43:36
Brilliant! Это было решением для сгруппированного табличного представления и работает на iOS 6.
Daniel 17.04.2013 06:14:46
также вы можете использовать предопределенный CGFLOAT_MIN для небольшого числа
Hofi 14.05.2017 20:18:03

Вы можете установить высоту отдельных строк раздела на 0. Кроме того, с заголовком раздела, если хотите. Источник данных все еще будет там, только не появится.

Раздел строки

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0) {
        if (_shouldHidden) {
            return 0.0;
        }
        else {
            return 55.0;
        }
    }
    else {
        return 55.0;
    }
}
1
26.06.2014 14:40:41
Что делать, если раздел имеет верхний и нижний колонтитулы? переопределим ли мы еще 4 метода, чтобы скрыть это? Слишком много ненужной работы, но все еще нет правильного способа достичь этого решения.
ACAkgul 14.11.2018 07:40:44

Попробуйте вот так:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    CGFloat headerHeight=10.f;
    if (section==0)
    {
        headerHeight=0.01f;
    }
    else
    {
        headerHeight=50.0f;
    }
    return headerHeight;
}
0
5.04.2015 01:22:38

Если вы вернете 0 для высоты раздела, Apple API проигнорирует его. Так что просто верните небольшое значение больше 0.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  if (section == 0) {
    return 1;
  }

  return 44;
}

Также реализуйте view для header и верните nil для раздела, который вы не хотите показывать.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  if (section == 0 && !self.personaCells.count) {
    return nil;
  }

  UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 44)];
  UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, headerView.frame.size.width, 20)];
  NSString *headerTitle = @"SAMPLE TITLE";
  headerLabel.text = headerTitle;    
  [headerView addSubview:headerLabel];
  return headerView;
}
1
16.07.2015 17:18:41

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

Шаг первый : реализовать два, funcопределенные в UITableViewDelegate - heightForRowAt -heightForHeaderInSection

Например, вот быстрые коды:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
{
   // if indexPath contains the specified section AND
   //    the condition for hiding this section is `true`
   //       return CGFloat(0)
   // else 
   //    return super.tableView(tableView, heightForRowAt: indexPath)
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 
{
   // similar logic to set header height
}

Шаг второй : определите функцию для установки ячеек, скрытых для определенного раздела, и вызовите ее из viewWillAppear:

private func setSectionVisible()
{
   /*
   if condition for visible is true
      let index = IndexPath(row:..., section:...)
      let cell = self.tableView.cellForRow(at: index)
      cell.isHiden = true
   */
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.setSectionVisible()
}

В случае, если вам нужно перезагрузить просмотр таблицы, вам может потребоваться setSectionVisible()снова позвонить .

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

0
27.11.2016 05:44:29

Чтобы скрыть раздел, даже в середине табличного представления вам понадобится все следующее

#define DEBUG_SECTION 1

#if ! DEBUG_BUILD
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return CGFLOAT_MIN;
    return [super tableView:tableView heightForHeaderInSection:section];
}
//------------------------------------------------------------------------------

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return CGFLOAT_MIN;
    return [super tableView:tableView heightForFooterInSection:section];
}
//------------------------------------------------------------------------------

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return nil;
    return [super tableView:tableView titleForHeaderInSection:section];
}
//------------------------------------------------------------------------------

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return nil;
    return [super tableView:tableView titleForFooterInSection:section];
}
//------------------------------------------------------------------------------

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == DEBUG_SECTION)
        return 0;
    return [super tableView:tableView numberOfRowsInSection:section];
}
//------------------------------------------------------------------------------
#endif // #if ! DEBUG_BUILD

если вы пропустили titleFor / headerFor ... вы получите несколько пустых строк,
если вы пропустили heightFor ... текст заголовка / нижнего колонтитула все равно будет отображаться

0
14.05.2017 20:48:05
Это все еще оставит немного места для пустого раздела. Очень легко увидеть с двумя таблицами в контроллере splitview.
lostintranslation 6.02.2019 16:36:26