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

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

альтернативный текст 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;

}

Ответы [ 10 ]

40 голосов
/ 24 октября 2010

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

Ваша проблема может быть решена, если вы установите 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];
}

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

17 голосов
/ 15 мая 2012

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

- (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 :)
    }
}
6 голосов
/ 23 марта 2010

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

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

4 голосов
/ 18 августа 2011

Это решение основано на решении 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;
}
3 голосов
/ 19 февраля 2015

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

- (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;
}
1 голос
/ 25 июля 2014

У меня была та же проблема в 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 в качестве высоты, секции будут отображаться с размером по умолчанию и перемещаться вниз по другим секциям.

0 голосов
/ 01 мая 2019

Я решил проблему, установив dataSource и делегата tableView , где я инициализирую 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
    }()
0 голосов
/ 01 мая 2019

Я решил эту проблему, установив dataSource и делегата tableView, где я инициализирую 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
    }()
0 голосов
/ 28 мая 2014

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

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

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

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

0 голосов
/ 23 марта 2010

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

"раздел 0" - это indexPath.section == 0

"раздел 2" - это indexPath.section == 1

"раздел 5" - это indexPath.section == 2

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...