UITableView: скрыть заголовок из пустого раздела - PullRequest
71 голосов
/ 16 марта 2012

У меня есть 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;
}

enter image description here Себастиан

Ответы [ 8 ]

132 голосов
/ 16 марта 2012

Вы должны установить 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
    }
}
56 голосов
/ 16 марта 2012

Что если в - tableView:viewForHeaderInSection: вы return nil, если счетчик разделов равен 0.

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

РЕДАКТИРОВАТЬ : Возможно, вы должны вернуть ноль также в titleForHeaderInSection, если numberOfRowsInSection равно 0.

РЕДАКТИРОВАТЬ : Реализовали ли выследующий метод?

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

РЕДАКТИРОВАТЬ : 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
}
53 голосов
/ 14 декабря 2013

В моей странной ситуации я должен вернуть:

viewForHeaderInSection -> nil

viewForFooterInSection -> nil (не забудьте о нижнем колонтитуле!)

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

heightForFooterInSection -> 0,01

только в этом случае пустые секцииисчезнуть полностью

10 голосов
/ 16 марта 2012

Взгляните на метод -[UITableViewDelegate tableView:heightForHeaderInSection:]. Особенно примечание, которое сопровождает его документацию:

До iOS 5.0 табличные представления автоматически изменяли размеры высот заголовков до 0 для разделов, где tableView:viewForHeaderInSection: вернул nil вид. В iOS 5.0 и более поздних версиях вы должны вернуть высота для каждого заголовка раздела в этом методе.

9 голосов
/ 06 августа 2013

Я знаю, что это старый вопрос, но я хотел бы добавить к нему. Я предпочитаю подход установки titleHeader на ноль, вместо изменения heightForHeaderInSection на 0, так как это может вызвать проблемы с 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 голосов
/ 27 августа 2015

В 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 голосов
/ 04 марта 2015

Это, кажется, правильный путь, он будет правильно анимирован и работает чисто ... как Apple собирался ...

Предоставить соответствующую информацию делегату tableView

Если в разделе нет элементов, вернуть 0.0f in:

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

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

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

Выполнить соответствующее удаление данных для tableView

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

Swift 4.2

Установите для параметра heightForHeaderInSection значение Zero, а если пользовательский вид сечения установлен, то для сечения без ячеек установите значение nil.

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)
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...