UITableView: приховати заголовок від порожнього розділу


76

у мене є UITableView, який відображає витрати за поточний місяць (див. знімок екрана):

Моя проблема в заголовку для порожніх розділів. чи є спосіб їх приховати? Дані завантажуються з coredata.

це код, який генерує заголовок заголовка:

TitleForHeader

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
    return nil;
} else {

NSDate *today = [NSDate date ];
int todayInt = [dataHandler getDayNumber:today].intValue;

NSDate *date = [NSDate dateWithTimeIntervalSinceNow:(-(todayInt-section-1)*60*60*24)];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]]];    
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *formattedDateString = [dateFormatter stringFromDate:date];
    return formattedDateString;}

}

ViewForHeader

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
    return nil;
} else {

    UIView *headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 30)];
    UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(4, 9, 312, 20)];
    UIView *top = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 5)];
    UIView *bottom = [[UIView alloc]initWithFrame:CGRectMake(0, 5, 312, 1)];

    [top setBackgroundColor:[UIColor lightGrayColor]];
    [bottom setBackgroundColor:[UIColor lightGrayColor]];

    [title setText:[expenseTable.dataSource tableView:tableView titleForHeaderInSection:section]];
    [title setTextColor:[UIColor darkGrayColor]];
    UIFont *fontName = [UIFont fontWithName:@"Cochin-Bold" size:15.0];
    [title setFont:fontName];


    [headerView addSubview:title];
    [headerView addSubview:top];
    [headerView addSubview:bottom];

    return headerView;

}

}

heightForHeader

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

NSLog(@"Height: %d",[tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0);
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section == 0]) {
    return 0;
} else {
    return 30;
}
}

numberOfRowsInSection

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {

int rows = 0;
for (Expense* exp in [dataHandler allMonthExpenses]) {
    if ([exp day].intValue == section) {
        rows++;
    }
}

return rows;
}

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

Відповіді:


57

Що якщо в - tableView:viewForHeaderInSection:ви, return nilякщо кількість розділів дорівнює 0.

РЕДАГУВАТИ : Ви можете використовувати numberOfRowsInSectionдля отримання кількості елементів у розділі.

РЕДАГУВАТИ : Ймовірно, вам слід повернути нуль також, titleForHeaderInSectionякщо numberOfRowsInSection0.

РЕДАГУВАТИ : Ви застосовували такий метод?

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

EDIT : приклад Swift 3

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    switch section {
    case 0:
        if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
            return "Title example for section 1"
        }
    case 1:
        if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
            return "Title example for section 2"
        }
    default:
        return nil // when return nil no header will be shown
    }
    return nil
}

на жаль, це не працює .. я оновив запитання новим кодом та новим скріншотом.
Себастьян Флюкігер

жодної помилки. щойно закінчив редагувати питання. тепер новий код і новий знімок екрана.
Себастьян Флюкігер

до речі, ви реалізували numberOfRowsInSection?
LuisEspinoza,

1
а що, якщо ви перевірите розмір заголовка розділу в перо? .. можливо, якщо ви використовуєте 0, ви отримаєте кращий результат .. оскільки ви встановлюєте його в коді.
LuisEspinoza,

2
Це старе питання зараз, але return nil;в titleForHeaderInSectionдосить для мене (після перевірки count > 0на цій ділянці , звичайно)
Patrick

135

tableView:heightForHeaderInSection:Для відповідних розділів потрібно встановити значення 0. Це те, що змінилося досить недавно і привело мене до пари. З UITableViewDelegateнього сказано ...

До iOS 5.0 подання таблиці автоматично змінювали висоту заголовків до 0 для розділів, де tableView: viewForHeaderInSection: повертав нульовий вигляд. У iOS 5.0 та новіших версіях потрібно повернути фактичну висоту для кожного заголовка розділу в цьому методі.

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

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return 0;
    } else {
        // whatever height you'd want for a real section header
    }
}

на жаль, це не працює .. я оновив запитання новим кодом та новим скріншотом.
Себастьян Флюкігер

3
Статичні таблиці дещо відрізняються. Цей код призначений для нестандартних подань заголовків таблиці, а не лише для title. Якщо ви встановлюєте a, titleвам потрібно буде повернутися nilдля виклику методу, tableView:titleForHeaderInSection:коли це доречно. Якщо ви використовуєте власні подання заголовків, ви повинні перевизначити viewForHeaderInSection. Якщо ви робите це, цей код повинен працювати. Якщо ні, мені знадобиться додаткова інформація, щоб допомогти вирішити проблему.
DBD

дивовижно ... велике спасибі. раніше я повертав такий бланк UIView: else { vw = [[UIView alloc]init]; [vw setHidden:YES]; }
Вайбхав Саран

я використовував viewforheader в розділі + вище коду і досконало працював в iOS 6 і навіть у нижчій версії. thnnxx buddyy
Amrit

Працював для мене - я на ios6
Ширіш Кумар

54

У моїй дивній ситуації я повинен повернутися:

viewForHeaderInSection -> нуль

 viewForFooterInSection -> nil (не забувайте про нижній колонтитул!)

heightForHeaderInSection -> 0,01 (не нуль!)

 heightForFooterInSection -> 0,01

лише в цьому випадку порожні розділи повністю зникають


10
Я зробив це, просто встановивши headerHeight на 0,01.
Akshit Zaveri

1
iOS 8.4 Я все ще міг бачити текст за допомогою 0,01, але 0,0 спрацював заміну чарівності func tableView (tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {if secctedTableData [section] .count == 0 {return CGFloat (0.0)} return CGFloat (40.0)}
DogCoffee

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

Навіть у iOS 12.1 вам все одно потрібно встановити висоту на 0.01.... iOS має деякі дивні помилки.
Supertecnoboff

10

Погляньте на метод -[UITableViewDelegate tableView:heightForHeaderInSection:]. Особливо примітка, яка додається до його документації:

До iOS 5.0 подання таблиці автоматично змінювали висоту заголовків до 0 для розділів, де tableView:viewForHeaderInSection: повертався nilподання. У iOS 5.0 та новіших версіях потрібно повернути фактичну висоту для кожного заголовка розділу в цьому методі.


спасибі, mch хлопці - погано оновлюю вас за пару годин і прийму і підтримаю все, що найкраще працювало :-)
Себастьян Флюкігер

2
на жаль, це не працює .. я оновив запитання новим кодом та новим скріншотом.
Себастьян Флюкігер

9

Я знаю, що це давнє запитання, але я хотів би додати до нього. Я віддаю перевагу підходу встановлення значення " titleHeaderнуль" перед зміною значення " heightForHeaderInSection0", оскільки це може спричинити проблеми з indexPath+1, звідки має бути, через те, що заголовок все ще там, але прихований.

Отже, з урахуванням сказаного і спираючись на відповідь DBD, ви можете встановити значення titleForHeaderInSection:нуль для розділів, у яких немає рядків, так:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    } else {
        // return your normal return
    }
}

7

У 2015 році, використовуючи iOS 8 та Xcode 6, для мене працювали:

/* Return the title for each section if and only if the row count for each section is not 0. */

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    }else{

    // here you want to return the title or whatever string you want to return for the section you want to display

    return (SomeObject*)someobjectArray[section].title;
    }
}

5

Це, здається, правильний спосіб, він буде анімувати правильно і працює чисто ... як задумав Apple ...

Надайте відповідну інформацію представнику tableView

Якщо в розділі немає елементів, поверніть 0,0f за:

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

..Також повернути нуль для:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

Виконайте відповідне видалення даних для tableView

  1. Телефонуйте [tableView beginUpdates];
  2. Видаліть елементи з вашого джерела даних, відстежуючи, де елементи були видалені ..
  3. Зателефонуйте deleteRowsAtIndexPathsіз indexPaths клітинок, які ви видалили.
  4. якщо у вашому джерелі даних немає елементів (тут ви отримаєте лише заголовок). Зателефонуйте, reloadSections:щоб оновити цей розділ. Це спричинить правильну анімацію та приховає / зсуне / зникне заголовок.
  5. Нарешті зателефонуйте, [tableView endUpdates];щоб закінчити оновлення ..

1
Дякуємо за підказку щодо reloadSections: :-) Все ще не можу змусити нічого працювати для мене з iOS11. Трохи дратує: /
firecall

Чому ми повинні дзвонити reloadSections? Я помітив, що якщо я не викликаю його, заголовки мого подання таблиці перекриваються (поки я не прокручу, тоді відображається правильний заголовок).
Supertecnoboff

2

Свіфт 4.2

Встановіть heightForHeaderInSection на Нуль, і якщо у вас є власний перегляд розділів, встановіть його на нуль для розділів без комірок.

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

func tableView(_ tableView: UITableView,
                   viewForHeaderInSection section: Int) -> UIView? {

        return tableView.dataSource?.tableView(tableView, numberOfRowsInSection: section) == 0 ? nil: headerView(tableView: tableView, section: section)
    }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.