Як приховати заголовок першого розділу в UITableView (згрупований стиль)


108

Оскільки дизайн представлень таблиць із використанням згрупованого стилю значно змінився з iOS 7, я хотів би приховати (або видалити) заголовок першого розділу. Поки що мені не вдалося цього досягти.

Дещо спрощений мій код виглядає приблизно так:

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

- (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        UIView* view = [[UIView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 640.0f, 0.0f)];
        return view;
    }
    return nil;
}

- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return nil;
    } else {
        // return some string here ...
    }
}

Якщо я поверну висоту 0, інші два способи ніколи не будуть називатися з індексом розділу 0. Однак порожній заголовок розділу все ще намальований із висотою за замовчуванням. (У iOS 6 називають два методи. Однак видимий результат однаковий.)

Якщо я поверну інше значення, заголовок розділу отримує вказану висоту.

Якщо я поверну 0,01, це майже правильно. Однак, коли я вмикаю "Кольорові нерівні зображення" в тренажері, він позначає всі комірки подання таблиці (що, здається, є логічним наслідком).

Відповіді на питання UITableView: сховати заголовок від порожнього розділу, схоже, вказують на те, що деякі люди успішно ховали заголовок розділу. Але це може стосуватися простого стилю (замість згрупованого).

Найкращий компроміс поки що - повернення висоти 0,5, що призводить до дещо товстішої лінії нижче панелі навігації. Однак я вдячний, якщо хтось знає, як заголовок першого розділу можна повністю приховати.

Оновлення

Відповідно до аналізу caglar ( https://stackoverflow.com/a/19056823/413337 ), проблема виникає лише в тому випадку, якщо подання таблиці міститься в навігаційному контролері.


Я не отримав цю частину => if (section == 0) view view; повернути нуль; тобто повернення виду, коли його перший розділ і нульове інакше?
Дзен

Ідея полягає в тому, щоб повернути вигляд з висотою 0 для першого розділу і повернути нуль для всіх інших розділів, щоб табличний вигляд використовував для них вид заголовка за замовчуванням. Нуль частина добре працює; у таблиці подано заголовок цих розділів. Але частина розділу 0 не має значення, оскільки метод ніколи не викликається section == 0.
Кодо

1
Ця відповідь здається короткою і милою. stackoverflow.com/a/23955420/3965
Містер Роджерс

Відповіді:


154

У мене є рішення, яке мені здається досить чистим. Тож я відповідаю на власне запитання.

Оскільки 0, оскільки висота заголовка першого розділу не працює, повертаюсь 1. Потім я використовую contentInset, щоб приховати цю висоту під панеллю навігації.

Завдання-C:

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

- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return nil;
    } else {
        // return some string here ...
    }
}

- (void) viewDidLoad
{
    [super viewDidLoad];

     self.tableView.contentInset = UIEdgeInsetsMake(-1.0f, 0.0f, 0.0f, 0.0);
}

Швидкий:

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return section == 0 ? 1.0 : 32
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.contentInset = UIEdgeInsets(top: -1, left: 0, bottom: 0, right: 0)
}

6
Використання висоти заголовка 0,1f ще краще для його приховування.
Чак Крутсінгер

4
Я спробував використовувати 0,1f. Але результат полягає в тому, що малюнки більше не вирівнюються до пікселів, що спричиняє розмиття та знижує продуктивність. Просто спробуйте в тренажері: він має можливість виділити проблемне вирівнювання.
Кодо

31
Насправді, кращою реалізацією (меншою ймовірністю в майбутньому зламатися) є використання CGFLOAT_MINзамість твердо кодованого значення. Іншими словами, не return 1.0fчи 0.1fзамість цього, return CGFLOAT_MINякщо Apple , коли - небудь зміни мінімально допустиме значення, ви будете мати код для зміни , якщо ви жорстко код, що повертається. Крім того, ви вже не знаєте, чи використовуєте ви найменше можливе значення. Використовуючи визначену константу, ви гарантовано використовуєте найменше можливе значення, і ваш код переживе зміни ОС.
Кріс Остмо

11
@Chris: Я боюся, що ти не здогадався. Я не повертаю дуже маленьке значення, але кратне розміру пікселя, щоб малюнок залишався вирівняним пікселем (для гарної продуктивності та чіткості). Потім я компенсую це за допомогою вставки вмісту. Це навряд чи зміниться в майбутньому, оскільки це значна, видима відстань, а не те, що ОС може ігнорувати.
Кодо

8
+1 Не використовуйте значення дробових пікселів як компенсацію інтерфейсу користувача.
Рікардо Санчес-Саес

52

Ось як приховати заголовок першого розділу в UITableView (згрупований стиль).

Swift 3.0 та Xcode 8.0 Рішення

  1. Делегат TableView повинен реалізувати метод heightForHeaderInSection

  2. У межах висотиForHeaderInSection поверніть найменше додатне число. (не нуль!)

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    
        let headerHeight: CGFloat
    
        switch section {
        case 0:
            // hide the header
            headerHeight = CGFloat.leastNonzeroMagnitude
        default:
            headerHeight = 21
        }
    
        return headerHeight
    }
    

6
повернення CGFloat.leastNonzeroMagnitude замість 0 допомогло мені. Дякую!
anoo_radha

Ідеальна відповідь, дякую
П'єр

До речі, CGFLOAT_MINдля objc є ідентичним CGFloat.leastNonzeroMagnitudeу Swift
DawnSong

36

Відповідь була дуже смішною для мене та моєї команди, і працювала як принадність

  • У програмі інтерфейсу просто перемістіть перегляд таблиці під інший вигляд в ієрархії подання.

ПРИЧИНА:

Ми помітили, що це відбувається лише для першого перегляду в Ієрархії перегляду, якщо цей перший вид є UITableView . Отже, всі інші подібні UITableView не мають цього дратівливого розділу, крім першого. Ми намагалися перемістити UITableView з першого місця в ієрархії перегляду, і все працювало так, як очікувалося.


1
У вас все ще виникає ефект матового скла на панелі навігації, коли ви прокручуєте подання таблиці?
Кодо

Цей ефект розмивання ви матимете, коли відповідно встановите таблицю ViewView. Вам потрібно встановити значення, contentInsetнаприклад, {0, 64, 0, 0}щоб зміщення 64 пікселів у верхній частині (рядок стану плюс панель навігації). Таблицю TableView потрібно прикріпити у верхній частині екрана, а не на topLayoutGuide (щоб вона досягла під навігаційною панеллю)
Julian F. Weinert

Якщо ви не використовуєте функцію "pull" для оновлення, це виглядатиме добре.
Майкл

2
Ого. Це працювало для мене в iOS 9 і просто підірвало мою думку.
виділити

Це має бути прийнятою відповіддю. Такий дивний клоп!
Одед Харт

25

Використовуйте цей трюк для згрупованого типу tableView

Скопіюйте пасту нижче коду для перегляду таблиці у методі viewDidLoad :

tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tableView.bounds.size.width, 0.01f)];

Я не пробував цього, але підозрюю, що це рішення має такий же недолік, як і деякі інші запропоновані рішення: малюнки більше не вирівнюються до пікселів, що спричиняє розмиття та знижує продуктивність. Симулятор може розкрити це: він має можливість виділити проблемне вирівнювання. Однак, якщо все-таки це округлення до 0, то справді це приємне рішення.
Кодо

Так, я думаю, що це округлює до 0. Оскільки я використовував його багато разів, але не знайшов розмитості в малюнках.
Нітеш Борад

Перегляд TableHeaderView та заголовка розділу? яка різниця,
AsifHabib

Або трохи коротше: _tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 1)].
mojuba

@AsifHabib: tableHeaderView розміщується вгорі всіх елементів таблиці. Це заголовок для самої таблиці. А перегляд заголовка розділу - це перегляд, який слід розмістити на кожному розділі Можна вказати багато переглядів заголовків розділів відповідно до вказаних жодних розділів таблиці. Але буде лише одне подання заголовка таблиці.
Нітеш Борад

21

цей спосіб добре.

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0 {
        return CGFloat.min
    }
    return 25
}

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if section == 0 {
        return nil
    }else {
        ...
    }
}

2
Це хороший варіант мого рішення, за винятком того, що він використовує дробові значення. Таким чином, текст і зображення більше не вирівнюються до пікселів, малювання сповільнюється, і результат може стати розмитим. Симулятор має опцію "Кольорові несогласовані зображення" для виявлення цієї проблеми.
Кодо

Працює чудово для таких людей, як я, використовуючи статичні комірки з контейнером
View

3
Swift 3> "CGFloat.min" перейменовано на "CGFloat.leastNormalMagnitude"
rjobidon

6

Я просто скопіював ваш код і спробував. Він працює нормально (спробував у тренажері). Я додав перегляд результатів. Ви хочете такого виду, правда? Або я неправильно зрозумів вашу проблему?

введіть тут опис зображення


1
Так, це в основному те, що я хочу, за винятком мого подання таблиці в контролері навігації. Чи може це змінити значення?
Кодо

2
Я додав tableView до контролера навігації, і ваша ситуація з'являється :) Я думаю, що в iOS 7 цю висоту заголовка виправте за замовчуванням у згрупованому стилі таблиці таблиць. Змінюючи кадр tableView, вигляд першого заголовка може бути прихованим. (Наприклад, встановити x = 0 y = -40). Однак я знаю, що це рішення не є хорошим рішенням.
caglar

1
Дуже дякую за вашу роботу. Отже, здається, що проблема виникає лише в тому випадку, коли у таблиці подання використовується згрупований стиль та міститься в контролері навігації.
Кодо

Намагаючись перейти з viewcontroller на tableviewcontroller, я не зміг виправити проблему із заголовком. Можливо, мені щось не вистачає, намагаючись перетворити це. (iOS 7.0.3 sim)
Євген Петров

1
Ця проблема також відображається на цьому знімку! 0-я клітина не починається від x: 0.0f & y: 0.0f.
Burhanuddin Sunelwala

6

Swift3: heightForHeaderInSection працює з 0, потрібно лише переконатися, що в заголовку встановлено clipsToBounds.

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
       return 0
}

якщо не встановити clipsToBounds прихований заголовок буде видно під час прокрутки.

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }

    header.clipsToBounds = true
}

1
clipsToBound = true дуже важливо, якщо ви плануєте повністю приховати подання заголовка розділу. Встановити його висоту в 0 / CGFLOAT_MIN недостатньо.
Altimac

5

Оновлення [19.09.17]: Стара відповідь більше не працює для мене в iOS 11. Спасибі Apple. Зробив наступне:

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 20.0f;
self.tableView.contentInset = UIEdgeInsetsMake(-18.0, 0.0f, 0.0f, 0.0);

Попередній відповідь:

Як було розміщено у коментарях Кріса Остомо, для мене працювало наступне:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return CGFLOAT_MIN; // to get rid of empty section header
}

Я підозрюю, що вміст вашого перегляду таблиці більше не вирівнюється до пікселів, що спричиняє розмиття та знижує продуктивність. Симулятор може розкрити це: він має можливість виділити проблемне вирівнювання. Однак, якщо все-таки це округлення до 0, то справді це приємне рішення.
Кодо

Ні, я не помітив жодних проблем із вмістом. Обмеження здалося прекрасним.
Маніндра Мохарана

1
Welp! Більше не працює в iOS 11! Моє виправлення тривало менше тижня .. 😞
Маніндра Мохарана

4

Ось як позбутися заголовка верхнього розділу в згрупованому UITableView в Swift:

tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))

3

У Swift 4.2 та багатьох попередніх версіях замість того, щоб висота першого заголовка була встановлена ​​на 0, як у інших відповідях, ви можете просто встановити інші заголовки nil. Скажімо, у вас є два розділи, і ви хочете, щоб у другому (тобто 1) було заголовку. У цьому заголовку буде текст Foobar :

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return section == 1 ? "Foobar" : nil
}

3

Спробуйте це, якщо ви хочете повністю видалити весь заголовок розділу

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return CGFloat.leastNormalMagnitude
}

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return CGFloat.leastNormalMagnitude
}

Це просто мені потрібно. Просте і легке рішення. 1+
iGhost

0

Я поки не можу коментувати, але подумав, що додам, що якщо у вас UISearchControllerна контролері встановлено UISearchBarяк ваш tableHeaderView, встановлення висоти першого розділу як 0 у heightForHeaderInSectionдійсно працює.

Я використовую self.tableView.contentOffset = CGPointMake(0, self.searchController.searchBar.frame.size.height);так, що панель пошуку за замовчуванням прихована.

Результатом є те, що для першого розділу немає заголовка, і прокрутка вниз покаже панель пошуку прямо над першим рядком.


0

Найпростіший на сьогоднішній день - повернутися nilабо ""в func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?розділ, де ви не бажаєте відображати заголовок.


0

Версія Swift: Swift 5.1
Здебільшого ви можете встановити висоту в delegate tableView таким чином:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
   return UIView(frame: CGRect(x: 0, y: 0, width: view.width, height: CGFloat.leastNormalMagnitude))
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
   return CGFloat.leastNormalMagnitude
}

Іноді, коли ви створили UITableView за допомогою Xib або Storyboard, відповідь вгору не працює. ви можете спробувати друге рішення:

let headerView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))
self.tableView.tableHeaderView = headerView

Сподіваюся, це працює для вас!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.