È 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.