Изменение поведения прокрутки по умолчанию в заголовке раздела UITableView

У меня есть UITableView с двумя разделами. Это простой вид таблицы. Я использую viewForHeaderInSection для создания пользовательских представлений для этих заголовков. Пока что так хорошо.

Поведение прокрутки по умолчанию заключается в том, что когда секция встречается, заголовок секции остается привязанным под панелью Nav, пока следующий раздел не прокрутится в поле зрения.

Мой вопрос заключается в следующем: могу ли я изменить поведение по умолчанию, чтобы заголовки разделов не были привязаны вверху, а скорее прокручивались под панелью навигации с остальными строками раздела?

Я пропустил что-то очевидное?

Спасибо.

Ответ 1

Как я решил эту проблему, нужно отрегулировать contentOffset в соответствии с contentInset в UITableViewControllerDelegate (extends UIScrollViewDelegate) следующим образом:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
       CGFloat sectionHeaderHeight = 40;
   if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
       scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
   } else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
       scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
   }
}

Единственная проблема заключается в том, что при прокрутке вверх до конца он немного отскакивает.


{ПРИМЕЧАНИЕ: "40" должно быть точной высотой вашего заголовка раздела 0. Если вы используете число, которое больше, чем высота заголовка раздела 0, вы увидите, что это касается чувства пальца (попробуйте "1000", и вы увидите, что поведение отказов выглядит странно вверху). если число соответствует высоте заголовка раздела 0, ощущение пальца кажется идеальным или почти идеальным.}

Ответ 2

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

Ответ 3

Если бы я это делал, я бы воспользовался тем, что UITableViews в стиле Plain имеют липкие заголовки, а в стиле Grouped - нет. Я бы, по крайней мере, попытался использовать пользовательскую ячейку таблицы, чтобы имитировать внешний вид ячеек Plain в таблице Grouped.

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

Ответ 4

Я знаю, что это происходит поздно, но я нашел окончательное решение!

Что вы хотите сделать, это если у вас есть 10 разделов, пусть DataSource вернется 20. Используйте четные числа для заголовков секций и нечетные числа для содержимого раздела. что-то вроде этого

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section%2 == 0) {
        return 0;
    }else {
        return 5;
    }
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if (section%2 == 0) {
        return [NSString stringWithFormat:@"%i", section+1];
    }else {
        return nil;
    }
}

Вуаля!: D

Ответ 5

Для решения этой проблемы необходимо выполнить несколько действий:

  • Задайте стиль представления таблицы UITableViewStyleGrouped
  • Установите представление таблицы backgroundColor на [UIColor clearColor]
  • Установите backgroundView в каждой ячейке представления таблицы на пустой вид с помощью backgroundColor [UIColor clearColor]
  • При необходимости установите представление таблицы rowHeight соответствующим образом или переопределите tableView:heightForRowAtIndexPath:, если отдельные строки имеют разную высоту.

Ответ 6

Первоначально опубликовано Здесь, быстрое решение с использованием IB. То же самое можно сделать программным, но довольно просто.

Вероятно, это проще для этого (с использованием IB):

Перетащите UIView в свой TableView, чтобы сделать его заголовком.

  • Задайте высоту представления заголовка до 100px
  • Установите tableview contentInset (вверху) на -100
  • Заголовки разделов теперь будут прокручиваться точно так же, как и любая обычная ячейка.

Некоторые люди прокомментировали, что это решение скрывает первый заголовок, однако я не заметил такой проблемы. Он отлично работал у меня и был самым простым решением, которое я видел до сих пор.

Ответ 7

Я не был доволен описанными здесь решениями, поэтому я попытался их объединить. Результатом является следующий код, вдохновленный @awulf и @cescofry. Это работает для меня, потому что у меня нет реального заголовка таблицы. Если у вас уже есть заголовок таблицы, вам, возможно, придется отрегулировать высоту.

// Set the edge inset
self.tableView.contentInset = UIEdgeInsetsMake(-23.0f, 0, 0, 0);

// Add a transparent UIView with the height of the section header (ARC enabled)
[self.tableView setTableHeaderView:[[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 23.0f)]];

Ответ 8

Просто измените стиль TableView:

self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];

Документация UITableViewStyle:

UITableViewStylePlain- Обычный стол. Любые верхние или нижние колонтитулы разделов отображаются в виде встроенных разделителей и плавают при прокрутке вида таблицы.

UITableViewStyleGrouped- Представление таблицы, в разделах которого представлены различные группы строк. Верхние и нижние колонтитулы не плавают.

Ответ 9

Select Grouped TableView style

Выберите стиль Grouped Table View из вашего TableView Attribute Inspector в раскадровке.

Ответ 10

Измените стиль TableView:

self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];

В соответствии с документацией на яблоко для UITableView:

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

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

Ответ 11

Установите заголовок таблицы таблицы с прозрачным представлением с одинаковой высотой заголовка в разрезе. Также запустите tableview с y-фреймом на -height.

self.tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, - height, 300, 400)];

UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)] autorelease];
[self.tableView setTableHeaderView:headerView];

Ответ 12

Я нашел альтернативное решение, использую первую ячейку каждого раздела вместо реального раздела заголовка, это решение не кажется таким чистым, но работает так хорошо, вы можете использовать определенную ячейку прототипа для раздела заголовков и в метод cellForRowAtIndexPath запрашивает indexPath.row == 0, если true, используйте ячейку прототипа заголовка, иначе используйте ячейку прототипа по умолчанию.

Ответ 13

Теперь, когда сгруппированный стиль выглядит в основном таким же, как простой стиль в iOS 7 (с точки зрения плоскостности и фона), для нас лучшим и самым легким (то есть наименее опасным) решением было просто изменить стиль представления таблицы на сгруппированные, Взаимодействие с contentInsets всегда было проблемой, когда мы включили навигационную панель прокрутки вверху. С помощью стиля сгруппированных таблиц он выглядит точно так же (с нашими ячейками), и заголовки разделов остаются фиксированными. Никакой прокручивающейся странности.

Ответ 14

Назначьте отрицательную вставку в tableView. Если у вас 22px заголовки заголовков, и вы не хотите, чтобы они были липкими, сразу после перезагрузки Data add:

self.tableView.contentInset = UIEdgeInsetsMake(-22, 0, 0, 0); 
self.tableView.contentSize = CGSizeMake(self.tableView.contentSize.width, self.tableView.contentSize.height+22); 

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

Ответ 15

Я добавляю таблицу в список прокрутки и, кажется, работает хорошо.

Ответ 16

Проверьте мой ответ здесь. Это самый простой способ реализовать заголовки неплавающих секций без каких-либо хаков.

Ответ 17

@LocoMike ответ лучше всего подходит для моего стола, но он сломался и при использовании нижних колонтитулов. Таким образом, это исправленное решение при использовании верхних и нижних колонтитулов:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return (self.sections.count + 1) * 3;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section % 3 != 1) {
        return 0;
    }
    section = section / 3;
    ...
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (section % 3 != 0) {
        return nil;
    }
    section = section / 3;
    ...
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section % 3 != 0) {
        return 0;
    }
    section = section / 3;
    ...
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    if (section % 3 != 2) {
        return 0;
    }
    section = section / 3;
    ...
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (section % 3 != 0) {
        return nil;
    }
    section = section / 3;
    ...
}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    if (section % 3 != 2) {
        return nil;
    }
    section = section / 3;
    ...
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    int section = indexPath.section;
    section = section / 3;
    ...
}

Ответ 18

Измените стиль TableView:

self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];

В соответствии с документацией на яблоко для UITableView:

UITableViewStylePlain- A plain table view. Any section headers or footers are displayed as inline separators and float when the table view is scrolled.

UITableViewStyleGrouped- A table view whose sections present distinct groups of rows. The section headers and footers do not float.
Hope this small change will help you ..

Ответ 19

Быстрая версия ответа @awulf, которая отлично работает!

func scrollViewDidScroll(scrollView: UIScrollView) {
    let sectionHeight: CGFloat = 80
    if scrollView.contentOffset.y <= sectionHeight {
        scrollView.contentInset = UIEdgeInsetsMake( -scrollView.contentOffset.y, 0, 0, 0)
    }else if scrollView.contentOffset.y >= sectionHeight {
        scrollView.contentInset = UIEdgeInsetsMake(-sectionHeight, 0, 0, 0)
    }
}

Ответ 20

Я узнал, что просто установка свойства tableHeaderView делает это, то есть:

 tableView.tableHeaderView = customView;

и что он.