Подтвердить что ты не робот

Сгруппированный UITableView показывает пустое место, когда раздел пуст

У меня есть сгруппированный UITableView, где не все секции могут отображаться сразу, а таблица управляется некоторыми данными, которые не каждая запись может иметь. Моя проблема в том, что записи, которые не имеют определенных разделов, отображаются в виде пробелов в таблице (см. Рисунок)

alt text http://img220.imageshack.us/img220/5633/screenshot20100322at228.png

Нет нижних колонтитулов/заголовков. Все, что я пропустил?

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self getRowCount:section];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

cell.textLabel.text = [NSString stringWithFormat:@"section: %d row: %d",indexPath.section,indexPath.row];
// Configure the cell...

return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    float height = 0.0;

    if([self getRowCount:indexPath.section] != 0){
        height = kDefaultRowHeight;
    }

    return height;

}
4b9b3361

Ответ 1

В приведенном выше снимке экрана ваш метод numberOfSectionsInTableView: возвращает значение 5? И тогда ваш метод getRowCount: (вызванный из numberOfRowsInSection:), возвращающий значение 0 для этих "отсутствующих" разделов (например, 1, 3 и 4)?

Если вам не нужны промежутки между ними, вероятным решением является только объявление количества разделов, которые вы хотите видеть. В приведенном выше примере вам нужно только вернуть значение 3 из numberOfSectionsInTableView:.

Ответ 2

У меня похожая ситуация, и моя модель данных действительно работает лучше, если я могу позволить ей иметь пустые разделы.

Ваша проблема может быть решена, если вы установите self.tableView.sectionHeaderHeight = 0; и self.tableView.sectionFooterHeight = 0; в свой контроллер таблиц. Они должны быть 0, потому что методы делегата каким-то образом игнорируют возвращаемое значение 0. Затем вам необходимо переопределить некоторые методы делегата:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (section==0)
        return sectionGapHeight;
    if ([self tableView:tableView numberOfRowsInSection:section]==0) {
        return 0;
    }
    return sectionGapHeight;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    if (section==[self numberOfSectionsInTableView:tableView]-1) {
        return sectionGapHeight;
    }
    return 0;
}
- (UIView *)sectionFiller {
    static UILabel *emptyLabel = nil;
    if (!emptyLabel) {
        emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        emptyLabel.backgroundColor = [UIColor clearColor];
    }
    return emptyLabel;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return [self sectionFiller];
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    return [self sectionFiller];
}

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

Ответ 3

Вот решение, которое сработало для меня

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    switch (section) {  
      case 1: case 3: case 5: return 20.0f; break;
      default: return 0.01f; // for some reason 0 is not accepted - give something :)
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    switch (section) {  
      case 1: case 3: case 5: return 20.0f; break;
      default: return 0.01f; // for some reason 0 is not accepted - give something :)
    }
}

Ответ 4

Это решение основано на решении user362178. Но сохраняет метки разделов без изменений:

Определите где-то в верхней части вашего кода:

#define HEIGHT_FOR_HEADER_AND_FOOTER 50

Добавить в вид загружен:

self.tableView.sectionHeaderHeight = 0;
self.tableView.sectionFooterHeight = 0; 

Добавьте следующие методы:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{
    // Needed because if this does not return a value, the header label of the section will
    // be at the top of the screen.
    if (section == 0)
    {
        return HEIGHT_FOR_HEADER_AND_FOOTER;
    }

    if ([self tableView:tableView numberOfRowsInSection:section] == 0) 
    {
        return 0;
    }
    else   
    {
        return HEIGHT_FOR_HEADER_AND_FOOTER;
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{
    // if last section
    if (section == [self numberOfSectionsInTableView:tableView] - 1) 
    {
        return HEIGHT_FOR_HEADER_AND_FOOTER;
    }

    return 0;
}

Ответ 5

Вот самое изящное решение, которое я нашел на основе всех ответов здесь, плюс этот ответ:

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

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

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) {
        return 0.01f;;
    }

    return UITableViewAutomaticDimension;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) {
        return 0.01f;;
    }

    return UITableViewAutomaticDimension;
}

Ответ 6

У меня была такая же проблема в iOS 7, и, наконец, я решил проверить уровень для заголовков и нижних колонтитулов, как сказал Рамеш:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
if ([[self.tableView objectAtIndex:section] count] == 0)
    return 0.01f;
else
    return 30.f;

}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.01f;

}

Любопытно, но если вы установите 0.f как высоту, разделы показываются с размером по умолчанию и перемещаются вниз по другим разделам.

Ответ 7

Я считаю, что с представлениями таблицы разделов каждый раздел должен существовать, и каждый раздел имеет буферную комнату для заголовка и нижнего колонтитула, независимо от того, как вы вставляете в них текст. Вам нужно удалить разделы, которые не используются. В вашем примере вы удалите разделы 1, 3 и 4. Это будет означать:

"section 0" is indexPath.section == 0

"section 2" is indexPath.section == 1

"раздел 5" является indexPath.section == 2

Если вы кодируете таким образом, верхние и нижние колонтитулы будут удалены, так как ячейка nil будет удалена.

Это не правильное кодирование, но я просто хотел дать вам представление о богословии. Надеюсь, это поможет.

Ответ 8

Ключ должен установить ноту таблицы sectionHeaderHeight и sectionFooterHeight.

Вы можете сделать это либо в viewDidLoad, либо в разделе Определенные пользователем атрибуты времени выполнения в вашем раскадровке /xib. По какой-то причине на вкладке "Размер инспектора" вы не можете установить высоту заголовка или нижнего колонтитула ниже 1.

Я обнаружил, что как только я это сделал, мне не нужно было переопределять какие-либо другие методы делегата особым образом. Я просто возвращаю 0 из numberOfRowsInSection и nil из titleForHeaderInSection для пустых разделов, и они не занимают места в моем представлении таблицы.

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

Ответ 9

Я решил проблему, установив tableView dataSource и делегировав, где я инициализирую tableView.

Примечание: помните, что вам может понадобиться сделать tableView ленивым для назначения при инициализации tableView.

lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.separatorStyle = .none
        tableView.backgroundColor = .white
        tableView.dataSource = self
        tableView.delegate = self
        return tableView
    }()

Ответ 10

Я решил проблему, установив tableView dataSource и делегировав, где я инициализирую tableView

Помните, что вам может понадобиться сделать tableView ленивым для назначения при инициализации tableView

lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.separatorStyle = .none
        tableView.backgroundColor = .white
        tableView.dataSource = self
        tableView.delegate = self
        return tableView
    }()