UITableView: скрыть заголовок из пустого раздела
У меня есть 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;
}
Себастиан
Ответы
Ответ 1
Что делать, если in - tableView:viewForHeaderInSection:
you return nil
, если количество секций равно 0.
EDIT:
Вы можете использовать numberOfRowsInSection
для получения количества элементов в разделе.
ИЗМЕНИТЬ:
Вероятно, вы должны вернуть нуль также в titleForHeaderInSection
, если numberOfRowsInSection
равно 0.
ИЗМЕНИТЬ:
Вы реализовали следующий метод?
-(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
}
Ответ 2
Вы должны установить 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
В моей странной ситуации я должен вернуться:
viewForHeaderInSection → nil
viewForFooterInSection → nil (не забывайте о нижнем колонтитуле!)
heightForHeaderInSection → 0.01 (не ноль!)
heightForFooterInSection → 0.01
только в этом случае пустые части полностью исчезают
Ответ 4
Взгляните на метод -[UITableViewDelegate tableView:heightForHeaderInSection:]
. Особенно примечание, прилагаемое к документации:
До iOS 5.0 вид таблицы автоматически изменил бы высоту заголовков до 0 для разделов, где tableView:viewForHeaderInSection:
вернул представление nil
. В iOS 5.0 и более поздних версиях вы должны высота для каждого заголовка раздела в этом методе.
Ответ 5
Я знаю, что это старый вопрос, но я хотел бы добавить к нему. Я предпочитаю подход 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
}
}
Ответ 6
В 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;
}
}
Ответ 7
Кажется, это правильный способ, он будет правильно одушевляться и работать чистым... поскольку Apple предназначалась...
Предоставить соответствующую информацию делегату tableView
Если в разделе нет элементов, возвращаем 0.0f в:
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
.. Также верните nil для:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
Сделайте соответствующее удаление данных для tableView
- Вызов
[tableView beginUpdates];
- Удалите элементы из вашего источника данных, отслеживая, где элементы были удалены..
- Вызовите
deleteRowsAtIndexPaths
с помощью indexPaths удаленных вами ячеек.
- если ваш источник данных не имеет в нем элементов (здесь вы должны получить только заголовок). Вызовите
reloadSections:
, чтобы перезагрузить этот раздел. Это вызовет правильную анимацию и скроет/сдвинет/увянет заголовок.
- Наконец, позвоните
[tableView endUpdates];
, чтобы завершить обновление.
Ответ 8
Swift 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)
}