Изменение размера шрифта для заголовков разделов UITableView


140

Может кто-нибудь проинструктировать меня, как проще всего изменить размер шрифта для текста в заголовке раздела UITableView?

У меня заголовки разделов реализованы следующим образом:

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

Затем я понимаю, как успешно изменить высоту заголовка раздела с помощью этого метода:

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

У меня есть ячейки UITableView, заполненные с помощью этого метода:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Однако я застрял в том, как на самом деле увеличить размер шрифта - или, если на то пошло, стиль шрифта - текста заголовка раздела?

Может кто-нибудь помочь? Спасибо.


Ответы:


119

К сожалению, вам, возможно, придется переопределить это:

В Objective-C:

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

В Swift:

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

Попробуйте что-то вроде этого:

В Objective-C:

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

    UILabel *myLabel = [[UILabel alloc] init];
    myLabel.frame = CGRectMake(20, 8, 320, 20);
    myLabel.font = [UIFont boldSystemFontOfSize:18];
    myLabel.text = [self tableView:tableView titleForHeaderInSection:section];

    UIView *headerView = [[UIView alloc] init];
    [headerView addSubview:myLabel];

    return headerView;
}

В Swift:

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

    let myLabel = UILabel()
    myLabel.frame = CGRect(x: 20, y: 8, width: 320, height: 20)
    myLabel.font = UIFont.boldSystemFont(ofSize: 18)
    myLabel.text = self.tableView(tableView, titleForHeaderInSection: section)

    let headerView = UIView()
    headerView.addSubview(myLabel)

    return headerView
}

1
Спасибо. Это сработало отлично. Очень признателен.
JRD8 06

6
Хотя это правильное решение, будьте осторожны с этим методом. Для заголовка длиной более одной строки вам придется выполнить расчеты высоты заголовка, tableView:heightForHeaderInSection:которые могут быть громоздкими.
Лео Натан

3
Пробовал, и хотя он работает, если вы прокручиваете таблицу вверх, метка заголовка остается на экране и перекрывает ячейки. :(
Plasma

2
@trss Я думаю, вы обнаружите, что это не ожидаемое поведение. Я не говорю о разделе заголовка, который остается там, только о ярлыке и его наложении на ячейки, когда они проходят под ним, что делает его настоящим беспорядком. Я нашел лучший способ добиться этого и отправлю его, как только найду его снова.
Plasma

1
@ mosca1337 нет необходимости создавать другое представление, вы можете получить фактический отображаемый UITableViewHeaderFooterView и настроить параметры.
Хуан Боэро

371

Другой способ сделать это - ответить на UITableViewDelegateметод willDisplayHeaderView. Переданное представление на самом деле является экземпляром UITableViewHeaderFooterView.

В приведенном ниже примере изменяется шрифт, а также центрируется текст заголовка по вертикали и горизонтали внутри ячейки. Обратите внимание, что вы также должны реагировать, чтобы heightForHeaderInSectionлюбые изменения высоты вашего заголовка учитывались в макете представления таблицы. (То есть, если вы решите изменить высоту заголовка в этом willDisplayHeaderViewметоде.)

Затем вы можете ответить на titleForHeaderInSectionметод повторного использования этого настроенного заголовка с другими заголовками разделов.

Цель-C

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;

    header.textLabel.textColor = [UIColor redColor];
    header.textLabel.font = [UIFont boldSystemFontOfSize:18];
    CGRect headerFrame = header.frame;
    header.textLabel.frame = headerFrame;
    header.textLabel.textAlignment = NSTextAlignmentCenter;
}

Swift 1.2

(Примечание: если ваш контроллер представления является потомком a UITableViewController, его нужно объявить как override func.)

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
{
    let header:UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView

    header.textLabel.textColor = UIColor.redColor()
    header.textLabel.font = UIFont.boldSystemFontOfSize(18)
    header.textLabel.frame = header.frame
    header.textLabel.textAlignment = NSTextAlignment.Center
}

Swift 3.0

Этот код также гарантирует, что приложение не выйдет из строя, если ваше представление заголовка отличается от UITableViewHeaderFooterView:

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }
    header.textLabel?.textColor = UIColor.red
    header.textLabel?.font = UIFont.boldSystemFont(ofSize: 18)
    header.textLabel?.frame = header.frame
    header.textLabel?.textAlignment = .center
}

3
Этот метод сработал для меня намного лучше, чем приведенный выше
Plasma

7
Лучший ответ, который я видел.
phatmann

2
Это был бы «правильный» способ настройки информации, при условии, что нет другой причины для создания подкласса (например, для добавления представлений). Кроме того, этот метод можно использовать для обновления текста заголовка для динамического типа. Просто используйте: header.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];и / или header.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];вместе с другими необходимыми шагами (см. Здесь: captechconsulting.com/blog/john-szumski/… )
Leanne

3
Это не изменяет размер представления заголовка, поэтому, если ваш шрифт больше или значительно отличается, например, Zapfino (не спрашивайте почему), он вырежет текст. Если вам придется рассчитывать размер самостоятельно, это беспорядок, и вам не стоит этого делать.
Лео Натан

@CocoaPriest В моей бета-версии не происходит сбоев. (GM посев 2)
Патрик Бассут

97

Хотя ответ mosca1337 является правильным решением, будьте осторожны с этим методом. Для заголовка с текстом длиной более одной строки вам придется выполнить расчеты высоты заголовка, tableView:heightForHeaderInSection:которые могут быть громоздкими.

Наиболее предпочтительным методом является использование API внешнего вида:

[[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setFont:[UIFont boldSystemFontOfSize:28]];

Это изменит шрифт, оставив при этом саму таблицу для управления высотой.

Для получения оптимальных результатов создайте подкласс табличного представления и добавьте его в цепочку включения (in appearanceWhenContainedIn:), чтобы убедиться, что шрифт изменяется только для определенных табличных представлений.


1
Если вы подклассифицируете, вы все равно вернете настраиваемый вид - tableView:viewForHeaderInSection:справа? В этом случае шрифт можно установить прямо здесь. Это то, что делает решение @ mosca1337.
trss

1
Ха-ха, ну, после вчерашнего дня я одурманен. Создайте подкласс табличного представления и добавьте его в список контейнеров. ;-)
Лео Натан

2
Это решение вызывает множество ошибок при вычислении реального размера нижнего / верхнего колонтитула. Я могу показать несколько примеров, когда заголовки обрезаются, когда настраивается собственный шрифт.
kas-kad

5
Swift 3 :UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)
Эрик Ходжинс

3
При этом размер метки изменяется неправильно, чтобы соответствовать шрифту в iOS 11. Кроме того, прокрутка вверх и вниз после загрузки представлений сбрасывает их к шрифту по умолчанию.
nickdnk 05

26

Для iOS 7 я использую это,


-(void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;

    header.textLabel.font = [UIFont boldSystemFontOfSize:10.0f];
    header.textLabel.textColor = [UIColor orangeColor];
}

Вот версия Swift 3.0 с изменением размера заголовка

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let header = view as? UITableViewHeaderFooterView {
        header.textLabel!.font = UIFont.systemFont(ofSize: 24.0)
        header.textLabel!.textColor = UIColor.orange          
    }
}

6
При этом размер заголовка не будет соответствовать новому шрифту.
Лео Натан,

@LeoNatan Как мы можем изменить размер заголовка, чтобы он соответствовал новому шрифту - можно ли это сделать с помощью этого метода?
SAHM

Я хотел уточнить, что я видел ваш ответ выше, но я хочу изменить шрифт только для ограничения размера, когда шрифт, выбранный пользователем (доступность), превышает определенный размер (поэтому не всегда). Я считаю, что мне нужно проверить и, возможно, изменить шрифт в willDisplayHeaderView, так есть ли способ пересчитать высоту просмотра, если шрифт будет изменен?
SAHM

19

Swift 3:

Самый простой способ отрегулировать только размер:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    let header = view as! UITableViewHeaderFooterView

    if let textlabel = header.textLabel {
        textlabel.font = textlabel.font.withSize(15)
    }
}

Это самый простой способ, который я ищу.
Райан

Работает в Swift 4! Не забывайте "override func .."
Матвей

8

Swift 2.0 :

  1. Замените заголовок раздела по умолчанию полностью настраиваемым UILabel.

Реализуйте viewForHeaderInSection, например:

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

    let sectionTitle: String = self.tableView(tableView, titleForHeaderInSection: section)!
    if sectionTitle == "" {
      return nil
    }

    let title: UILabel = UILabel()

    title.text = sectionTitle
    title.textColor = UIColor(red: 0.0, green: 0.54, blue: 0.0, alpha: 0.8)
    title.backgroundColor = UIColor.clearColor()
    title.font = UIFont.boldSystemFontOfSize(15)

    return title
  }
  1. Измените заголовок по умолчанию (оставьте значение по умолчанию).

Реализуйте willDisplayHeaderView, например:

  override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    if let view = view as? UITableViewHeaderFooterView {
      view.backgroundView?.backgroundColor = UIColor.blueColor()
      view.textLabel!.backgroundColor = UIColor.clearColor()
      view.textLabel!.textColor = UIColor.whiteColor()
      view.textLabel!.font = UIFont.boldSystemFontOfSize(15)
    }
  }

Помните: если вы используете статические ячейки, заголовок первого раздела заполняется выше, чем заголовки других разделов, из-за верхней части UITableView; чтобы исправить это:

Реализуйте heightForHeaderInSection, например:

  override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

    return 30.0 // Or whatever height you want!
  }

4

Swift 4 версия ответа Лео Натана :

UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)

Если вы хотите установить собственный шрифт, вы можете использовать

if let font = UIFont(name: "font-name", size: 12) {
    UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = font
}

К сожалению, это не меняет размер кадра.
nickdnk 07

3

С помощью этого метода вы также можете установить размер шрифта, стиль шрифта и фон заголовка . для этого есть 2 метода

Первый метод

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section{
        UITableViewHeaderFooterView *header = (UITableViewHeaderFooterView *)view;
        header.backgroundView.backgroundColor = [UIColor darkGrayColor];
        header.textLabel.font=[UIFont fontWithName:@"Open Sans-Regular" size:12];
        [header.textLabel setTextColor:[UIColor whiteColor]];
    }

Второй метод

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 30)];
//    myLabel.frame = CGRectMake(20, 8, 320, 20);
    myLabel.font = [UIFont fontWithName:@"Open Sans-Regular" size:12];
    myLabel.text = [NSString stringWithFormat:@"   %@",[self tableView:FilterSearchTable titleForHeaderInSection:section]];

    myLabel.backgroundColor=[UIColor blueColor];
    myLabel.textColor=[UIColor whiteColor];
    UIView *headerView = [[UIView alloc] init];
    [headerView addSubview:myLabel];
    return headerView;
}

1

Swift 2:

Как просил OP, отрегулируйте только размер, не устанавливая его как системный жирный шрифт или что-то еще:

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
        if let headerView = view as? UITableViewHeaderFooterView, textLabel = headerView.textLabel {

            let newSize = CGFloat(16)
            let fontName = textLabel.font.fontName
            textLabel.font = UIFont(name: fontName, size: newSize)
        }
    }

1

Вот оно, здесь вам нужно выполнить 1 шаг. # Свифт 5

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    
    let header = view as? UITableViewHeaderFooterView
    header?.textLabel?.font = UIFont.init(name: "Montserrat-Regular", size: 14)
    header?.textLabel?.textColor = .greyishBrown
}

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

Удачи


0

Это мое решение с быстрым 5.

Чтобы полностью контролировать вид раздела заголовка, вам необходимо использовать метод tableView (: viewForHeaderInsection: :) в вашем контроллере, как показано в предыдущем сообщении. Однако есть еще один шаг: для повышения производительности Apple рекомендует не создавать каждый раз новое представление, а повторно использовать представление заголовка, как и повторно использовать ячейку таблицы. Это выполняется методом tableView.dequeueReusableHeaderFooterView (withIdentifier :). Но у меня возникла проблема: как только вы начнете использовать эту функцию повторного использования, шрифт не будет работать должным образом. Другие вещи, такие как цвет, выравнивание, все в порядке, но только шрифт. Есть некоторые обсуждения, но я заставил его работать следующим образом.

Проблема в tableView.dequeueReusableHeaderFooterView (withIdentifier :) не похож на tableView.dequeneReuseCell (:), который всегда возвращает ячейку. Первый вернет ноль, если никто не доступен. Даже если он возвращает представление заголовка повторного использования, это не ваш исходный тип класса, а UITableHeaderFooterView. Поэтому вам нужно выносить суждение и действовать в соответствии со своим собственным кодексом. В принципе, если оно равно нулю, получите новый заголовок. Если не nil, принудительно применить, чтобы вы могли контролировать.

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let reuse_header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "yourHeaderID")
        if (reuse_header == nil) {
            let new_sec_header = YourTableHeaderViewClass(reuseIdentifier:"yourHeaderID")
            new_section_header.label.text="yourHeaderString"
            //do whatever to set color. alignment, etc to the label view property
            //note: the label property here should be your custom label view. Not the build-in labelView. This way you have total control.
            return new_section_header
        }
        else {
            let new_section_header = reuse_section_header as! yourTableHeaderViewClass
            new_sec_header.label.text="yourHeaderString"
            //do whatever color, alignment, etc to the label property
            return new_sec_header}

    }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.