Zmiana rozmiaru czcionki dla nagłówków sekcji UITableView

139

Czy ktoś może mi poinstruować, jak najłatwiej zmienić rozmiar czcionki dla tekstu w nagłówku sekcji UITableView?

Mam tytuły sekcji zaimplementowane następującą metodą:

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

Następnie rozumiem, jak skutecznie zmienić wysokość nagłówka sekcji za pomocą tej metody:

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

Mam komórki UITableView wypełnione przy użyciu tej metody:

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

Jednak utknąłem, jak faktycznie zwiększyć rozmiar czcionki - lub jeśli o to chodzi, styl czcionki - tekstu nagłówka sekcji?

Czy ktoś może pomóc? Dzięki.

JRD8
źródło
1
Swift wersja
Juan Boero

Odpowiedzi:

118

Niestety może być konieczne zastąpienie tego:

W celu C:

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

W Swift:

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

Spróbuj czegoś takiego:

W celu 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;
}

W 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
}
mosca1337
źródło
1
Dziękuję Ci. To działało doskonale. Bardzo cenione.
JRD8
5
Chociaż jest to poprawne rozwiązanie, zachowaj ostrożność przy tej metodzie. W przypadku nagłówka dłuższego niż jeden wiersz będziesz musiał wykonać obliczenia wysokości nagłówka, tableView:heightForHeaderInSection:która może być uciążliwa.
Leo Natan
3
Wypróbowałem to i chociaż to działa, jeśli przewiniesz tabelę w górę, etykieta nagłówka pozostaje na ekranie i nakłada komórki. :(
Plasma
2
@trss Myślę, że zauważysz, że to nie jest oczekiwane zachowanie. Nie mówię o pozostającej tam sekcji nagłówka, tylko o etykiecie i jej super nałożeniu na komórki, gdy przechodzą pod nią, co sprawia, że ​​wygląda to na prawdziwy bałagan. Znalazłem lepszy sposób na osiągnięcie tego i opublikuję go ponownie, gdy znajdę go ponownie.
Plazma
1
@ mosca1337 nie ma potrzeby tworzenia innego widoku, możesz wyświetlić rzeczywisty „UITableViewHeaderFooterView” i dostosować parametry.
Juan Boero,
368

Innym sposobem, aby to zrobić, byłaby odpowiedź na UITableViewDelegatemetodę willDisplayHeaderView. Przekazany widok jest w rzeczywistości instancją pliku UITableViewHeaderFooterView.

Poniższy przykład zmienia czcionkę, a także wyśrodkowuje tekst tytułu w komórce w pionie i poziomie. Zwróć uwagę, że powinieneś również zareagować, aby heightForHeaderInSectionwszelkie zmiany wysokości nagłówka zostały uwzględnione w układzie widoku tabeli. (Oznacza to, że jeśli zdecydujesz się zmienić wysokość nagłówka w tej willDisplayHeaderViewmetodzie).

Następnie możesz odpowiedzieć na titleForHeaderInSectionmetodę ponownego użycia tego skonfigurowanego nagłówka z różnymi tytułami sekcji.

Cel 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

(Uwaga: jeśli kontroler widoku jest potomkiem a UITableViewController, należałoby to zadeklarować jako 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

Ten kod zapewnia również, że aplikacja nie ulegnie awarii, jeśli widok nagłówka jest inny niż 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
}
Mark Semsel
źródło
3
Ta metoda zadziałała dla mnie znacznie lepiej niż ta powyżej
Plasma
6
Najlepsza odpowiedź, jaką widziałem.
phatmann
2
Byłby to „właściwy” sposób dostosowania informacji przy założeniu, że nie ma innego powodu do tworzenia podklasy (na przykład dodawania widoków). Ponadto ta metoda może służyć do aktualizowania tekstu nagłówka dla typu dynamicznego. Po prostu użyj: header.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];i / lub header.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];wraz z innymi potrzebnymi krokami (patrz tutaj: captechconsulting.com/blog/john-szumski/… )
leanne
3
Nie zmienia to rozmiaru widoku nagłówka, więc jeśli Twoja czcionka jest większa lub znacząco się różni, na przykład Zapfino (nie pytaj dlaczego), tekst zostanie wycięty. Jeśli musisz sam obliczyć rozmiar, to bałagan i nie powinieneś tego robić.
Leo Natan
@CocoaPriest Nie ulega awarii w mojej wersji beta, chociaż. (Materiał siewny GM 2)
Patrick Bassut
96

Chociaż odpowiedź mosca1337 jest poprawnym rozwiązaniem, bądź ostrożny z tą metodą. W przypadku nagłówka z tekstem dłuższym niż jeden wiersz będziesz musiał wykonać obliczenia wysokości nagłówka, tableView:heightForHeaderInSection:która może być uciążliwa.

Znacznie preferowaną metodą jest użycie interfejsu API wyglądu:

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

Spowoduje to zmianę czcionki, pozostawiając jednocześnie stół do samodzielnego zarządzania wysokościami.

Aby uzyskać optymalne wyniki, podklasuj widok tabeli i dodaj go do łańcucha zawierania (in appearanceWhenContainedIn:), aby upewnić się, że czcionka zostanie zmieniona tylko dla określonych widoków tabeli.

Leo Natan
źródło
1
W przypadku tworzenia podklas, czy w każdym razie zwracałbyś niestandardowy widok z - tableView:viewForHeaderInSection:prawej strony? W takim przypadku czcionkę można ustawić bezpośrednio w tym miejscu. I tak właśnie działa rozwiązanie @ mosca1337.
trss
1
Haha, cóż, jestem woozey po wczorajszym dniu. Podklasuj widok tabeli i dodaj go do listy kontenerów. ;-)
Leo Natan
2
To rozwiązanie powoduje wiele błędów przy obliczaniu rzeczywistego rozmiaru stopki / nagłówka. Mogę pokazać kilka przykładów, kiedy tytuły są przycinane podczas ustawiania niestandardowej czcionki.
kas-kad
5
Swift 3 :UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)
Eric Hodgins
3
Nie powoduje to poprawnej zmiany rozmiaru etykiety w celu dopasowania do czcionki w systemie iOS 11. Ponadto przewijanie w górę iw dół po załadowaniu widoków powoduje zresetowanie ich do domyślnej czcionki.
nickdnk
25

Na iOS 7 używam tego,


-(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];
}

Oto wersja Swift 3.0 ze zmianą rozmiaru nagłówka

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          
    }
}
Maria
źródło
6
Nie spowoduje to dopasowania rozmiaru widoku nagłówka do nowej czcionki.
Leo Natan
@LeoNatan Jak możemy dopasować widok nagłówka do nowej czcionki - czy można to zrobić tą metodą?
SAHM
Chciałem wyjaśnić, że widziałem twoją powyższą odpowiedź, ale chcę tylko zmienić czcionkę, aby ograniczyć rozmiar, gdy wybrana przez użytkownika czcionka (dostępność) przekracza pewien rozmiar (więc nie zawsze). Uważam, że muszę sprawdzić i ewentualnie zmienić czcionkę w willDisplayHeaderView, więc czy istnieje sposób, aby przeliczyć wysokość widoku, jeśli czcionka zostanie zmieniona?
SAHM
19

Swift 3:

Najprostszy sposób dostosowania tylko rozmiaru:

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)
    }
}
jeff-ziligy
źródło
To najłatwiejszy sposób, którego szukam.
Ryan
Działa w Swift 4! Nie zapomnij o „override func ..”
Matvey
8

Swift 2.0 :

  1. Zastąp domyślny nagłówek sekcji w pełni konfigurowalnym UILabel.

Zaimplementuj viewForHeaderInSection, na przykład:

  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. Zmień domyślny nagłówek (zachowuje domyślny).

Zaimplementuj willDisplayHeaderView, na przykład:

  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)
    }
  }

Pamiętaj: jeśli używasz komórek statycznych, pierwszy nagłówek sekcji jest wyściełany wyżej niż inne nagłówki sekcji ze względu na górną część UITableView; aby to naprawić:

Zaimplementuj heightForHeaderInSection, na przykład:

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

    return 30.0 // Or whatever height you want!
  }
Elliott Davies
źródło
4

Swift 4 wersja Leo Natan odpowiedź jest

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

Jeśli chcesz ustawić niestandardową czcionkę, możesz użyć

if let font = UIFont(name: "font-name", size: 12) {
    UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = font
}
Giorgio
źródło
Niestety nie zmienia to rozmiaru ramki.
nickdnk
3

Dzięki tej metodzie możesz ustawić rozmiar czcionki, styl czcionki i tło nagłówka . są na to 2 metody

Pierwsza metoda

- (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]];
    }

Druga metoda

- (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;
}
Anup Gupta
źródło
1

Swift 2:

Zgodnie z zapytaniem OP dostosuj tylko rozmiar, nie ustawiając go jako pogrubionej czcionki systemowej lub cokolwiek innego:

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)
        }
    }
Juan Boero
źródło
0

To jest moje rozwiązanie z szybką 5.

Aby w pełni kontrolować widok sekcji nagłówka, musisz użyć metody tableView (: viewForHeaderInsection: :) w swoim kontrolerze, jak pokazano w poprzednim poście. Jest jednak kolejny krok: aby poprawić wydajność, firma Apple zaleca, aby nie generować nowego widoku za każdym razem, ale ponownie używać widoku nagłówka, tak jak ponowne wykorzystanie komórki tabeli. Jest to metoda tableView.dequeueReusableHeaderFooterView (withIdentifier:). Ale problem, który miałem, był taki, że gdy zaczniesz używać tej funkcji ponownego użycia, czcionka nie będzie działać zgodnie z oczekiwaniami. Inne rzeczy, takie jak kolor, wyrównanie wszystko w porządku, ale tylko czcionka. Jest kilka dyskusji, ale sprawiłem, że zadziałało jak poniżej.

Problem polega na tym, że tableView.dequeueReusableHeaderFooterView (withIdentifier :) różni się od tabeli tableView.dequeneReuseCell (:), która zawsze zwraca komórkę. Pierwsza zwróci zero, jeśli nikt nie jest dostępny. Nawet jeśli zwraca widok nagłówka ponownego użycia, nie jest to oryginalny typ klasy, ale UITableHeaderFooterView. Musisz więc dokonać oceny i postępować zgodnie z własnym kodeksem. Zasadniczo, jeśli jest zerowy, uzyskaj zupełnie nowy widok nagłówka. Jeśli nie zero, wymuś rzucenie, abyś mógł kontrolować.

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}

    }
JerryH
źródło