UITableView: viewForHeaderInSection: nie wywołano podczas reloadData:


128

Skonfigurowałem tableview z poprawnymi powiązaniami delegata i źródła danych. Metoda reloadData wywołuje źródło danych i metody delegata, z wyjątkiem metod viewForHeaderInSection:.

Dlaczego to jest takie?


31
Czy heightForHeaderInSection:wdrożono?
rano

Czy ustawiłeś wartość dla TableView sectionHeaderHeight?
Carter Medlin

Odpowiedzi:


258

Korzystanie z tableView:viewForHeaderInSection:wymagań, które również wdrażasz tableView:heightForHeaderInSection:. Powinno to zwrócić odpowiednią niezerową wysokość nagłówka. Upewnij się również, że nie implementujesz również tableView:titleForHeaderInSection:. Powinieneś używać tylko jednego lub drugiego ( viewForHeaderlub titleForHeader).


3
Upewnij się, że w podpisie metody nie ma literówki. Jedna zła litera oznacza, że ​​nie zostanie wywołana. Sprawdź też obudowę. Upewnij się również, że zwracasz 0 z numberOfSections.
rmaddy

wszystko jest poprawne i kompiluje się poprawnie. Problem, który chciałem zrozumieć, dotyczy czasu wywołania metody .. tableView: viewForHeaderInSection jest wywoływana, gdy tabela ma zostać wyświetlona, ​​a nie jako część wykonania synchronizacji [ tableview reloadData]
inforeqd

@maddy OMG Dziękuję, to takie głupie z mojej strony, że stworzyłem swoje instancje, ale nie dołączyłem ich do mojej tablicy
Happiehappie

5
Możesz mieć jedno i drugie. viewForHeaderInSection: będzie miał pierwszeństwo przed titleForHeaderInSection: Jedynym wymaganiem jest to, że w widoku tabeli ustawisz wartość ratedSectionHeaderHeight na coś innego niż 0, w przeciwnym razie viewForHeaderInSection: nigdy nie zostanie wywołany
2017

Dodanie do komentarza @ romrom: jeśli zaimplementowałeś oba titleForHeaderInSection:i, viewForHeaderInSection:a widok zwrócony z tego ostatniego jest podklasą, UITableViewHeaderFooterViewto textLabel.textjest automatycznie ustawiany na wersję titleForHeaderInSection:napisu pisaną wielkimi literami . Aby temu zapobiec, nie implementuj titleForHeaderInSection:ani nie używaj etykiety niestandardowej zamiast etykiety dziedziczonej textLabel.
Ortwin Gentz

40

Sztuczka polega na tym, że te dwie metody należą do różnych UITableViewprotokołów: tableView:titleForHeaderInSection:jest to UITableViewDataSourcemetoda protokołu, do której tableView:viewForHeaderInSectionnależy UITableViewDelegate.

To znaczy:

  • Jeśli zaimplementujesz metody, ale przypiszesz siebie tylko jako dataSourcefor UITableView, Twoja tableView:viewForHeaderInSectionimplementacja zostanie zignorowana.

  • tableView:viewForHeaderInSectionma wyższy priorytet. Jeśli zaimplementujesz obie metody i przypiszesz siebie zarówno jako, jak dataSourcei delegatedla UITableView, zwrócisz widoki nagłówków sekcji, ale Twój tableView:titleForHeaderInSection:zostanie zignorowany.

Próbowałem też usunąć tableView:heightForHeaderInSection:; działało dobrze i nie miało wpływu na powyższe procedury. Ale dokumentacja mówi, że jest to wymagane tableView:viewForHeaderInSectiondo prawidłowego działania; więc dla bezpieczeństwa warto to również wdrożyć.


6
Zrobiłeś mój dzień !!! Zapomniałem przypisać UITableViewDelegatedo self, bo pomyślałem, że tableView:viewForHeaderInSectionto UITableViewDataSourcemetoda. Dziękuję Ci!
denis631

1
„tableView: viewForHeaderInSection” nie jest istotne. Najważniejsze jest, abyś w jakiś sposób zwrócił wzrost. Możesz to osiągnąć poprzez 1. oszacowanie lub 2. wartość zakodowaną na stałe lub 3. a titleForHeaderktóra ma rozmiar wewnętrzny. Rozmiar wewnętrzny jest obliczany na podstawie rodziny czcionek i rozmiaru.
Miód

28

@rmaddy jest nieprawdziwe regułę, dwukrotnie: w rzeczywistości, tableView:viewForHeaderInSection:czy nie wymagają także wdrożenia tableView:heightForHeaderInSection:, a także jest perfekcyjnie zadzwonić zarówno titleForHeaderi viewForHeader. Prawidłowo podam regułę tylko do protokołu:

Zasada jest taka, viewForHeaderże nie zostanie wywołana, chyba że w jakiś sposób nadasz nagłówkowi wysokość. Możesz to zrobić na trzy sposoby:

  • Wdrażaj tableView:heightForHeaderInSection:.

  • Nakryj do stołu sectionHeaderHeight.

  • Call titleForHeader(to w jakiś sposób nadaje nagłówkowi domyślną wysokość, jeśli w przeciwnym razie nie ma takiej).

Jeśli nie zrobisz żadnej z tych rzeczy, nie będziesz mieć nagłówków i viewForHeadernie zostaniesz wywołany. Dzieje się tak, ponieważ bez wysokości środowisko wykonawcze nie będzie wiedziało, jak zmienić rozmiar widoku, więc nie zawraca sobie głowy pytaniem o jeden.


Z dokumentacji dla tableView:viewForHeaderInSection:: „Ta metoda działa poprawnie tylko wtedy, gdy tableView:heightForHeaderInSection:jest również zaimplementowana”.
rmaddy

1
W porządku. Co mówią doktorzy, mówią. Teraz eksperymentuj. Fakty są takie, jak powiedziałem.
mat.

A jak możesz mieć oba titleForHeaderInSectioni viewForHeaderInSection? Widok tabeli wywoła tylko jeden z dwóch (zapominam, który w tej chwili ma pierwszeństwo).
rmaddy

1
W rzeczywistości jest jeszcze jeden element układanki, który czasami viewForHeader jest wywoływany bez żadnego z tych trzech sposobów przypisywania wysokości. Zdarzyło mi się to, że mój viewForHeaderzostał sprawdzony i nagłówki pokazały się dobrze, aż pewnego dnia, bez żadnej zmiany z mojej strony, nie . Wtedy zacząłem eksperymentować, aby odkryć, jakie mają viewForHeaderbyć minimalne wymagania . Teraz już wiem. A teraz ty też.
mat.

2
@texas Nie, nie robię Xamarin. Dodanie kolejnego poziomu pośrednictwa do szkieletów Cocoa po prostu spowodowałoby eksplozję mojej głowy. :)
mat.

20

Dawanie estimatedSectionHeaderHeighti sectionHeaderHeightwartości rozwiązały mój problem. na przykład, self.tableView.estimatedSectionHeaderHeight = 100 self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension


Mój problem zaczął się po aktualizacji do Swift 3.1. To rozwiązanie rozwiązało problem.
zevij

@pbuchheit Apple Docs mówi, że jest dostępny od iOS 7.0+, zajrzyj tutaj, developer.apple.com/documentation/uikit/uitableview/…
Sharukh Mastan,

@Sharukh Mastan Wygląda na to, że masz rację. Z jakiegoś powodu otrzymałem ostrzeżenie, kiedy próbowałem użyć tej właściwości, ale zniknęło po wykonaniu czystej kompilacji.
pbuchheit

7

Wychodząc z odpowiedzi rmaddy, próbowałem ukryć widok nagłówka i zwracałem 0,0f dla „tableView: heightForHeaderInSection” i widoku z wysokości 0 tableView:viewForHeaderInSection.

Po zmianie z return 1.0fna return 0.0fin faktycznie tableView:heightForHeaderInSectionwywołano metodę delegata tableView:viewForHeaderInSection.

Okazuje się, że mój pożądany efekt działa bez konieczności używania "tableView: heightForHeaderInSection"; ale może to być przydatne dla innych, którzy mają problem z wywołaniem metody delegata „tableView: heightForHeaderInSection”.


5

Należy zaimplementować tableView:heightForHeaderInSection:i ustawić wysokość nagłówka> 0.

Ta metoda delegata jest zgodna z viewForHeaderInSection:metodą.

Mam nadzieję, że to pomoże.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
         return 40;
}

Czy sprawdziłeś, że Twoja odpowiedź faktycznie działa? Ponieważ ejeśli uważnie czytasz, jest powiedziane, że początkowo wywoływana jest metoda viewForHeaderInSection. Nie jest wywoływana tylko wtedy, gdy stół jest ponownie ładowany!
Karlis

5

Warto krótko zaznaczyć, że jeśli Twoja realizacja tableView:heightForHeaderInSection:zwrotów UITableViewAutomaticDimension, to tableView:viewForHeaderInSection:nie zostanie wywołana.

UITableViewAutomaticDimensionzakłada, że UITableViewHeaderFooterViewzostanie użyty standard wypełniony metodą delegata tableView:titleForHeaderInSection:.

Z komentarzy w UITableView.h:

Zwrócenie tej wartości z tableView:heightForHeaderInSection:lub tableView:heightForFooterInSection:skutkuje wysokością pasującą do wartości zwróconej z tableView:titleForHeaderInSection:lub tableView:titleForFooterInSection:jeśli tytuł nie jest zerowy.


1
jeśli ustawisz estimatedSectionHeaderHeightjakąś wartość, tableView:viewForHeaderInSectionzostanie wywołany (podobnie jak działa automatyczne wymiary dla wierszy)
GreatWiz

Ciekawe, dzięki. W wersji 7.1 ta subtelność szacowanej wysokości była ważna dla komórek , więc mogła być również w przypadku nagłówków - ale teraz nie jest to szczególnie istotne!
Benjohn,

3

Właśnie miałem problem z nagłówkami, które nie były wyświetlane w iOS 7.1 , ale działały dobrze z późniejszymi wersjami, które testowałem, wyraźnie z 8.1 i 8.4.

Dla dokładnie tego samego kodu 7.1 w ogóle nie wywoływał żadnej z metod delegata nagłówka sekcji, w tym: tableView:heightForHeaderInSection:i tableView:viewForHeaderInSection:.

Po eksperymentach stwierdziłem, że usunięcie tej linii z moich viewDidLoadutworzonych nagłówków pojawia się ponownie w wersji 7.1 i nie ma wpływu na inne wersje, które testowałem:

// _Removing_ this line _fixed_ headers on 7.1
self.tableView.estimatedSectionHeaderHeight = 80;

… Więc wydaje się, że jest tam jakiś konflikt, przynajmniej w wersji 7.1.


3

Ten sam problem wystąpił ze mną, ale ponieważ korzystałem z automatycznego obliczania wysokości z xCode 9 , nie mogę podać żadnej wyraźnej wartości wysokości, jak wspomniano powyżej. Po kilku eksperymentach otrzymałem rozwiązanie , musimy zastąpić tę metodę, ponieważ

-(CGFloat)tableView:(UITableView *)tableView 
         estimatedHeightForHeaderInSection:(NSInteger)section
{
      return 44.0f;
}

Chociaż mam zaznaczone obie opcje

  1. Automatyczne obliczanie wysokości
  2. Automatyczne obliczanie szacowanej wysokości

ze scenorysu, jak mówi Apple, ale nadal mam ten dziwny błąd.

Uwaga : ten błąd był wyświetlany tylko w wersji IOS-10, a nie w wersji IOS-11 . Może to błąd z xCode. Dzięki


0

Oto, co znalazłem ( Swift 4 ) (dzięki temu komentarzowi do innego pytania)

Czy użyłem titleForHeaderInSection czy viewForHeaderInSection - nie chodziło o to, że nie były wywoływane, gdy przewijano widok tabeli i ładowano nowe komórki, ale wszelkie wybory czcionek, które wybrałem dla textLabel headerView, pojawiały się tylko na tym, co było początkowo widoczne po załadowaniu , a nie podczas przewijania tabeli.

Poprawka to willDisplayHeaderView:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let header = view as? UITableViewHeaderFooterView {
        header.textLabel?.font = UIFont(name: yourFont, size: 42)
    }
}

0

W moim przypadku utworzyłem widok nagłówka, używając UITableviewCelli zwracając komórkę w viewForHeaderInSectionten sposób

return cell

zmieniono to na

return cell.contentView 

Pracował dla mnie.


0

W moim przypadku

viewForHeaderInSection

został zaimplementowany w odległej klasie pochodnej, która nie zawracała sobie głowy stokrotką w superklasie.


0

Przyczyną viewForHeaderInSectionbraku połączenia jest jeden z dwóch powodów:

Albo nie skonfigurowałeś swojego UITableViewDelegate, albo UITableViewDelegatenieprawidłowo skonfigurowałeś .


0

W moim przypadku to dlatego, że nie wdrożyłem:

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

-1

Czasami ustawienie tableview.delegatelub datasource = nilw metodach viewWillAppear:lub viewDidAppear:może powodować ten problem. Upewnij się, że tego nie robisz ...


-1

Wycinałem i wklejałem następujące dwie metody z projektu Swift 2 do mojego projektu Swift 3, które nigdy nie zostały wywołane, ponieważ w języku Swift 3 te metody muszą mieć znak „-” przed pierwszą nazwą parametru.

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

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

    let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: B2BTrolleyHeaderFooterView.reuseIdentifier) as! B2BTrolleyHeaderFooterView        
    return headerView
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.