È possibile ottenere l'altezza dell'intestazione della sezione della vista tabella dinamica utilizzando il layout automatico?


112

Novità di iOS 8, puoi ottenere celle di visualizzazione tabella dinamiche al 100% semplicemente impostando l'altezza della riga stimata, quindi disporre i tuoi elementi nella cella utilizzando il layout automatico. Se il contenuto aumenta di altezza, anche la cella aumenterà di altezza. Questo è estremamente utile e mi chiedo se la stessa impresa possa essere realizzata per le intestazioni di sezione in una vista tabella?

Si può, ad esempio, creare un UIViewin tableView:viewForHeaderInSection:, aggiungere una vista UILabelsecondaria, specificare vincoli di layout automatico per l'etichetta rispetto alla vista e fare in modo che la vista aumenti in altezza per adattarsi al contenuto dell'etichetta, senza doverla implementare tableView:heightForHeaderInSection:?

La documentazione per gli viewForHeaderInSectionstati: "Questo metodo funziona correttamente solo quando tableView: heightForHeaderInSection: è implementato anche." Non ho sentito se qualcosa è cambiato per iOS 8.

Se non è possibile farlo, qual è il modo migliore per imitare questo comportamento?

Risposte:


275

Questo è possibile. È nuovo proprio accanto alle altezze delle celle dinamiche implementate in iOS 8.

È molto semplice. Basta aggiungere questo in viewDidLoad:

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

Quindi sovrascrivi viewForHeaderInSectione usa Layout automatico per vincolare gli elementi nella tua vista come ritenuto opportuno. Questo è tutto! Non c'è bisogno di implementare heightForHeaderInSection. E in realtà sectionHeaderHeightnon è nemmeno necessario dichiararlo, l'ho aggiunto solo per chiarezza.

Tieni presente che in iOS 11, le celle e le visualizzazioni di intestazione / piè di pagina utilizzano le altezze stimate per impostazione predefinita. L'unica cosa da fare è fornire un'altezza stimata per informare meglio il sistema su cosa aspettarsi. Il valore predefinito è UITableViewAutomaticDimensionma dovresti fornire una stima migliore che è l'altezza media che saranno, se possibile.


3
È bello se funziona, ma i documenti non lo menzionano, e nemmeno la sessione WWDC se ricordo bene. I documenti per UITableViewAutomaticDimensiondire "se restituisci questa costante in tableView:heightForHeaderInSection:o tableView:heightForFooterInSection:, UITableViewutilizza un'altezza che si adatta al valore restituito da tableView:titleForHeaderInSection:o tableView:titleForFooterInSection:(se il titolo non lo è nil)."
— Aaron Brager

28
Questo non ha funzionato per me. La mia intestazione di sezione è stata in grado di calcolare automaticamente l'altezza, ma si sovrappone alle celle nella sezione. Sto impostando la mia visualizzazione dell'intestazione utilizzando un file xib e impostando i miei vincoli nel generatore di interfacce. È questo il mio problema? Dove state creando i vincoli? Grazie!
— CoBrA2168

5
Come promesso, ecco il codice di esempio: github.com/ebetabox/DynamicCellSectionHeight
— PakitoV

10
Un altro punto chiave qui, le celle della tabella devono essere configurate anche per il calcolo dell'altezza automatica (UITableViewAutomaticDimension) affinché funzioni sulle sezioni.
— Bob Spryn

9
Devi avere estimatedSectionHeaderHeighto tableView:estimatedHeightForHeaderInSection:AND sectionHeaderHeighto tableView:heightForHeaderInSection:. Inoltre, se si utilizzano i metodi delegato, è necessario restituire un valore maggiore di 1,00 per la stima (comportamento completamente non documentato), altrimenti NON verrà chiamato il delegato per l'altezza e verrà utilizzata l'altezza dell'intestazione della vista tabella predefinita.
— Vadoff

29

Ciò può essere ottenuto impostando (o restituendo) la estimatedSectionHeaderHeightvisualizzazione della tabella.

Se l'intestazione della sezione si sovrappone alle celle dopo l'impostazioneestimatedSectionHeaderHeight , assicurati di utilizzare anche un file estimatedRowHeight.

(Aggiungo questa risposta perché il secondo paragrafo contiene una risposta a un problema che può essere trovato dopo aver letto tutti i commenti che alcuni potrebbero perdere.)


1
Grazie, dopo aver impostato estimatedRowHeightquesto funziona come un fascino :)
— sz ashik

1
Questo è vero anche se NON stai usando UITableViewAutomaticDimension per le righe. Grazie per avermi risparmiato un'ora.
— Ryan Romanchuk

14

Sono rimasto bloccato nello stesso problema in cui l'intestazione stava ottenendo un'altezza zero fino a quando non fornisco un'altezza fissa nel delegato per heighForHeaderInSection.

Ho provato molte soluzioni che includono

self.tableView.sectionHeaderHeight = UITableView.automaticDimension
self.tableView.estimatedSectionHeaderHeight = 73

Ma niente ha funzionato. Anche il mio cellulare utilizzava i layout automatici appropriati. Le righe stavano cambiando la loro altezza dinamicamente utilizzando il codice seguente, ma l'intestazione di sezione non lo era.

self.tableView.estimatedRowHeight = 135
self.tableView.rowHeight = UITableView.automaticDimension

La correzione è estremamente semplice e anche strana, ma ho dovuto implementare i metodi delegato invece di 1 codice di riga per estimatedSectionHeaderHeighte sectionHeaderHeightche va come segue per il mio caso.

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

func tableView(_ tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
    73
}

11

Swift 4+

funzionante (testato al 100%)

Se hai bisogno sia della sezione che della riga con altezza dinamica basata sul contenuto, puoi utilizzare il codice seguente:

Su viewDidLoad () scrivi queste righe:

    self.globalTableView.estimatedRowHeight = 20
    self.globalTableView.rowHeight = UITableView.automaticDimension

    self.globalTableView.sectionHeaderHeight =  UITableView.automaticDimension
    self.globalTableView.estimatedSectionHeaderHeight = 25;

Ora abbiamo impostato l'altezza della riga e l'altezza della sezione utilizzando i metodi UITableView Delegate:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
   {
       return UITableView.automaticDimension
   }
   func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

       return UITableView.automaticDimension

   }

NOTA a questa ottima risposta. A partire dal 2020 sembra essere corretto utilizzare SOLO le quattro proprietà in viewDidLoad.
— Fattie

NOTA a questa ottima risposta. A partire dal 2020 hai bisogno delle due linee "inutili" che danno un'altezza stimata (diciamo, 20 o giù di lì).
— Fattie

6

Provai

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;

ma non ha dimensionato correttamente l'intestazione con l'etichetta multilinea. Aggiunto questo per risolvere il mio problema:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Recalculates height
    tableView.beginUpdates()
    tableView.endUpdates()
}

definire le funzioni dell'origine dati tableView:estimatedHeightForHeaderInSectione tableView:heightForHeaderInSectioninvece di definire in viewDidLoad.
— Keith Yeoh

Ho trovato che l'impostazione estimatedSectionHeaderHeightè necessaria solo sotto iOS 11
— doctorBroctor

1

Nel mio caso:

  1. impostare a livello di codice non funziona .

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension.

  1. ambientato nello storyboard non funziona .

  2. override ha heightForHeaderInSection funzionato .

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

ambiente di prova:

  • Mac OS 10.13.4
  • Versione XCode 9.4.1
  • Simulatore iPhone 8 Plus

0

Sì, per me funziona. Devo apportare ulteriori modifiche come di seguito:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let label = UILabel()

    label.numberOfLines = 0
    label.text          = my own text

    return label
}

-2

Ho modificato la risposta di iuriimoz . Metodo viewWillAppear appena sostituito:

tableView.sectionHeaderHeight = UITableViewAutomaticDimension
tableView.estimatedSectionHeaderHeight = 25


override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Recalculates height
    tableView.layoutIfNeeded() 
}

Aggiungi anche tableView.layoutIfNeeded () a

override func viewDidAppear(_ animated: Bool) {

    super.viewDidAppear(animated)
    tableView.layoutIfNeeded()
}

Per iOS 10

tableView.beginUpdates()
tableView.endUpdates()

hanno l'effetto di animazione "dissolvenza" su viewWillAppear per me

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.