Modifica della dimensione del carattere per le intestazioni di sezione UITableView


139

Qualcuno può darmi istruzioni sul modo più semplice per modificare la dimensione del carattere per il testo in un'intestazione della sezione UITableView?

Ho implementato i titoli delle sezioni usando il seguente metodo:

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

Quindi, capisco come modificare correttamente l'altezza dell'intestazione della sezione utilizzando questo metodo:

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

Ho le celle UITableView popolate usando questo metodo:

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

Tuttavia, sono bloccato su come aumentare effettivamente la dimensione del carattere - o del resto lo stile del carattere - del testo dell'intestazione della sezione?

Qualcuno può aiutare per favore? Grazie.


1
Versione rapida
Juan Boero,

Risposte:


118

Sfortunatamente, potresti dover eseguire l'override di questo:

In Objective-C:

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

In Swift:

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

Prova qualcosa del genere:

In 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;
}

In 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
Grazie. Questo ha funzionato perfettamente. Molto apprezzato.
JRD8,

5
Mentre questa è una soluzione corretta, fai attenzione con questo metodo. Per un'intestazione più lunga di una riga, dovrai eseguire i calcoli dell'altezza dell'intestazione in tableView:heightForHeaderInSection:cui può essere ingombrante.
Leo Natan,

3
Ho provato questo e mentre funziona se si scorre la tabella verso l'alto, l'etichetta dell'intestazione rimane sullo schermo e si sovrappone alle celle. :(
Plasma

2
@trss Penso che troverai questo comportamento non previsto. Non sto parlando della sezione dell'intestazione che rimane lì, solo dell'etichetta e del suo super imposto alle celle mentre passano sotto di essa facendola sembrare un vero casino. Ho trovato un modo migliore per raggiungere questo obiettivo e lo riporterò una volta che lo troverò di nuovo.
Plasma

1
@ mosca1337 non è necessario creare un'altra vista, è possibile visualizzare l'effettivo "UITableViewHeaderFooterView" e regolare i parametri.
Juan Boero,

368

Un altro modo per farlo sarebbe rispondere al UITableViewDelegatemetodo willDisplayHeaderView. La vista passata è in realtà un'istanza di a UITableViewHeaderFooterView.

L'esempio seguente modifica il carattere e centra anche il testo del titolo verticalmente e orizzontalmente all'interno della cella. Tieni presente che dovresti anche rispondere per heightForHeaderInSectionfare in modo che eventuali modifiche all'altezza della testata siano prese in considerazione nel layout della vista tabella. (Cioè, se si decide di modificare l'altezza dell'intestazione in questo willDisplayHeaderViewmetodo.)

È quindi possibile rispondere al titleForHeaderInSectionmetodo per riutilizzare questa intestazione configurata con titoli di sezione diversi.

Objective-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

(Nota: se il controller della vista è un discendente di a UITableViewController, questo dovrebbe essere dichiarato come 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

Questo codice garantisce inoltre che l'app non si arresti in modo anomalo se la visualizzazione dell'intestazione è diversa da 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
Questo metodo ha funzionato molto meglio per me rispetto a quello sopra
Plasma

6
La migliore risposta che abbia mai visto.
Phatmann,

2
Questo sarebbe il modo "corretto" di regolare le informazioni, supponendo che non vi siano altri motivi per sottoclassare (come ad esempio l'aggiunta di viste). Inoltre, questo metodo può essere utilizzato per aggiornare il testo dell'intestazione per Tipo dinamico. Usa semplicemente: header.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];e / o header.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];insieme agli altri passaggi necessari (vedi qui: captechconsulting.com/blog/john-szumski/… )
leanne,

3
Questo non ridimensiona la vista dell'intestazione, quindi se il tuo carattere è più grande o significativamente diverso, come Zapfino (non chiedere perché), taglierà il testo. Se devi calcolare le dimensioni da solo, è un casino e non dovresti farlo.
Leo Natan,

@CocoaPriest Non si blocca nella mia versione beta, però. (GM seed 2)
Patrick Bassut,

96

Mentre la risposta di mosca1337 è una soluzione corretta, fai attenzione a questo metodo. Per un'intestazione con testo più lungo di una riga, dovrai eseguire i calcoli dell'altezza dell'intestazione in tableView:heightForHeaderInSection:cui può essere ingombrante.

Un metodo molto preferito è usare l'API di aspetto:

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

Questo cambierà il carattere, lasciando comunque il tavolo per gestire le altezze stesse.

Per risultati ottimali, eseguire la sottoclasse della vista tabella e aggiungerla alla catena di contenimento (in appearanceWhenContainedIn:) per assicurarsi che il carattere venga modificato solo per le viste tabella specifiche.


1
In caso di sottoclasse, restituiresti comunque una vista personalizzata da - tableView:viewForHeaderInSection:destra? Nel qual caso il carattere può essere impostato proprio lì. Questa è la soluzione di @ mosca1337.
trss,

1
Haha, beh, sono un pazzo dopo ieri. Sottoclasse la vista tabella e aggiungerla all'elenco dei contenitori. ;-)
Leo Natan,

2
Questa soluzione causa molti bug nel calcolo della dimensione reale del piè di pagina / intestazione. Posso mostrare alcuni esempi quando i titoli vengono tagliati mentre è impostato il carattere personalizzato.
kas-kad,

5
Swift 3 :UILabel.appearance(whenContainedInInstancesOf: [UITableViewHeaderFooterView.self]).font = UIFont.boldSystemFont(ofSize: 28)
Eric Hodgins il

3
Questo non ridimensiona correttamente l'etichetta per adattarla al carattere su iOS 11. Inoltre, lo scorrimento verso l'alto e verso il basso dopo il caricamento delle viste li riporta al carattere predefinito.
Nickdnk,

25

Per iOS 7 lo uso,


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

Ecco la versione Swift 3.0 con ridimensionamento dell'intestazione

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
Ciò non ridimensionerà la vista dell'intestazione per adattarla al nuovo carattere.
Leo Natan,

@LeoNatan Come possiamo dimensionare la vista dell'intestazione per adattarla al nuovo carattere - può essere fatto con questo metodo?
SAHM,

Volevo chiarire che ho visto la tua risposta di cui sopra, ma voglio solo cambiare il carattere per limitare la dimensione quando un carattere selezionato dall'utente (accessibilità) supera una certa dimensione (quindi, non sempre). Credo di dover controllare e possibilmente cambiare il carattere in willDisplayHeaderView, quindi c'è un modo per ricalcolare l'altezza della vista se il carattere viene cambiato?
SAHM,

19

Swift 3:

Il modo più semplice per regolare solo le dimensioni:

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

Questo è il modo più semplice che sto cercando.
Ryan,

Funziona in Swift 4! Non dimenticare "override func .."
Matvey,

8

Swift 2.0 :

  1. Sostituisci l'intestazione di sezione predefinita con UILabel completamente personalizzabile.

Implementare viewForHeaderInSection, in questo modo:

  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. Modifica l'intestazione predefinita (mantiene l'impostazione predefinita).

Implementa willDisplayHeaderView, in questo modo:

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

Ricorda: se stai usando celle statiche, la prima intestazione di sezione è imbottita più in alto rispetto alle altre intestazioni di sezione a causa della parte superiore di UITableView; per risolvere questo problema:

Implementare heightForHeaderInSection, in questo modo:

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

    return 30.0 // Or whatever height you want!
  }

4

La versione Swift 4 di Leo Natan è la risposta

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

Se si desidera impostare un carattere personalizzato, è possibile utilizzare

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

Questo non ridimensiona la cornice, sfortunatamente.
Nickdnk,

3

Con questo metodo puoi anche impostare la dimensione del carattere, lo stile del carattere e lo sfondo dell'intestazione . ci sono 2 metodi per questo

Primo metodo

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

Secondo metodo

- (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:

Come richiesto da OP, regola solo la dimensione, non impostandola come carattere grassetto di sistema o altro:

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

0

Questa è la mia soluzione con swift 5.

Per controllare completamente la vista in sezione dell'intestazione, è necessario utilizzare il metodo tableView (: viewForHeaderInsection: :) nel controller, come mostrato nel post precedente. Tuttavia, c'è un ulteriore passo: per migliorare le prestazioni, apple consiglia di non generare una nuova vista ogni volta, ma di riutilizzare la vista dell'intestazione, proprio come riutilizzare la cella della tabella. Questo è con il metodo tableView.dequeueReusableHeaderFooterView (withIdentifier:). Ma il problema che ho avuto è che una volta che inizi a utilizzare questa funzione di riutilizzo, il carattere non funzionerà come previsto. Altre cose come il colore, l'allineamento tutto bene ma solo il carattere. Ci sono alcune discussioni ma l'ho fatto funzionare come segue.

Il problema è tableView.dequeueReusableHeaderFooterView (withIdentifier :) non è come tableView.dequeneReuseCell (:) che restituisce sempre una cella. Il primo restituirà un valore zero se nessuno è disponibile. Anche se restituisce una vista dell'intestazione di riutilizzo, non è il tipo di classe originale, ma UITableHeaderFooterView. Quindi devi esprimere il tuo giudizio e agire secondo il tuo codice. Fondamentalmente, se è pari a zero, ottieni una nuova visualizzazione dell'intestazione. In caso contrario, forza a lanciare in modo da poter controllare.

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}

    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.