UITableView: viewForHeaderInSection: tidak dipanggil selama reloadData:

127

Saya telah mengatur tampilan tabel dengan tautan delegasi dan sumber data yang benar .. metode reloadData memanggil sumber data dan metode delegasi kecuali untuk viewForHeaderInSection:.

Kenapa begitu?

inforeqd
sumber
30
Apakah ini heightForHeaderInSection:diterapkan?
usam
Sudahkah Anda menetapkan nilai untuk TableView sectionHeaderHeight?
Carter Medlin

Jawaban:

256

Penggunaan tableView:viewForHeaderInSection:mengharuskan Anda juga menerapkan tableView:heightForHeaderInSection:. Ini akan menghasilkan tinggi non-nol yang sesuai untuk header. Pastikan juga Anda tidak menerapkan tableView:titleForHeaderInSection:. Anda hanya boleh menggunakan satu atau yang lain ( viewForHeaderatau titleForHeader).

rmaddy
sumber
3
Pastikan tidak ada kesalahan ketik pada tanda tangan metode. Satu huruf yang salah berarti itu tidak akan dipanggil. Periksa kopernya juga. Pastikan juga Anda mengembalikan 0 dari numberOfSections.
rmaddy
semuanya benar dan mengkompilasi dengan benar .. masalah yang ingin saya pahami adalah sekitar waktu ketika metode ini disebut .. tableView: viewForHeaderInSection dipanggil ketika tabel baru saja akan ditampilkan dan bukan sebagai bagian dari eksekusi synch dari [ tableview reloadData]
inforeqd
@maddy OMG Terima kasih, saya sangat bodoh karena saya membuat instance saya tetapi saya tidak menambahkan ke array saya
Happiehappie
4
Anda benar-benar dapat memiliki keduanya. viewForHeaderInSection: akan didahulukan dari titleForHeaderInSection: Satu-satunya persyaratan adalah Anda menetapkan estimasiSectionHeaderHeight pada tampilan tabel Anda dengan sesuatu yang berbeda dari 0, jika tidak viewForHeaderInSection: tidak akan pernah dipanggil
romrom
Menambahkan ke komentar @ romrom: jika Anda telah mengimplementasikan keduanya titleForHeaderInSection:dan viewForHeaderInSection:dan tampilan yang dikembalikan dari yang terakhir adalah subkelas UITableViewHeaderFooterViewmaka textLabel.textsecara otomatis diatur ke versi all-caps dari titleForHeaderInSection:string. Untuk mencegah perilaku ini, jangan menerapkan titleForHeaderInSection:atau menggunakan label khusus alih-alih yang diwarisi textLabel.
Ortwin Gentz
40

Kuncinya adalah bahwa kedua metode tersebut milik UITableViewprotokol yang berbeda : tableView:titleForHeaderInSection:adalah UITableViewDataSourcemetode protokol, di mana tableView:viewForHeaderInSectionmilik UITableViewDelegate.

Itu berarti:

  • Jika Anda menerapkan metode tetapi menetapkan diri Anda hanya sebagai dataSourceuntuk UITableView, tableView:viewForHeaderInSectionimplementasi Anda akan diabaikan.

  • tableView:viewForHeaderInSectionmemiliki prioritas yang lebih tinggi. Jika Anda menerapkan kedua metode dan menetapkan diri sebagai dataSourcedan delegateuntuk UITableView, Anda akan mengembalikan tampilan untuk header bagian tetapi Anda tableView:titleForHeaderInSection:akan diabaikan.

Saya juga mencoba menghapus tableView:heightForHeaderInSection:; itu bekerja dengan baik dan tampaknya tidak mempengaruhi prosedur di atas. Tetapi dokumentasi mengatakan bahwa itu diperlukan untuk tableView:viewForHeaderInSectionbekerja dengan benar; jadi untuk amannya adalah bijaksana untuk mengimplementasikan ini juga.

Yunus Nedim Mehel
sumber
6
Kamu membuat hariku !!! Lupa untuk menetapkan UITableViewDelegateke self, karena saya pikir, bahwa tableView:viewForHeaderInSectionadalah UITableViewDataSourcemetode. Terima kasih!
denis631
1
"tableView: viewForHeaderInSection" tidak penting. Yang penting adalah Anda entah bagaimana mengembalikan ketinggian. Anda dapat mencapainya melalui 1. estimasi atau 2. nilai hardcode atau 3. titleForHeaderyang memiliki ukuran intrinsik. Ukuran intrinsik dihitung berdasarkan Keluarga Font dan ukuran.
Sayang
28

@rmaddy telah salah saji aturan, dua kali: pada kenyataannya, tableView:viewForHeaderInSection:tidak tidak mengharuskan Anda juga menerapkan tableView:heightForHeaderInSection:, dan juga itu adalah baik-baik saja untuk memanggil kedua titleForHeaderdan viewForHeader. Saya akan menyatakan aturan dengan benar hanya untuk catatan:

Aturannya sederhana yang viewForHeadertidak akan dipanggil kecuali Anda entah bagaimana memberikan tinggi header. Anda dapat melakukan ini dalam kombinasi dari tiga cara:

  • Implementasikan tableView:heightForHeaderInSection:.

  • Atur meja sectionHeaderHeight.

  • Panggil titleForHeader(ini entah bagaimana memberikan tinggi standar header jika tidak memiliki header).

Jika Anda tidak melakukan hal-hal itu, Anda tidak akan memiliki header dan viewForHeadertidak akan dipanggil. Itu karena tanpa ketinggian, runtime tidak akan tahu cara mengubah ukuran tampilan, jadi tidak perlu meminta.

matt
sumber
Dari dokumen untuk tableView:viewForHeaderInSection:: "Metode ini hanya berfungsi dengan benar bila tableView:heightForHeaderInSection:juga diterapkan.".
rmaddy
1
Baik. Apa kata dokter, kata mereka. Sekarang bereksperimen. Faktanya adalah seperti yang telah saya nyatakan.
matt
Dan bagaimana Anda bisa memiliki keduanya titleForHeaderInSectiondan viewForHeaderInSection? Tampilan tabel hanya akan memanggil salah satu dari keduanya (saya lupa yang diutamakan saat ini).
rmaddy
1
Sebenarnya ada satu lagi potongan teka-teki, yang kadang - kadangviewForHeader disebut tanpa salah satu dari ketiga cara menetapkan ketinggian. Saya mengalami hal ini, di mana saya viewForHeaderdipanggil dan tajuk muncul dengan baik, sampai suatu hari, tanpa perubahan pada bagian saya, mereka tidak . Saat itulah saya mulai bereksperimen untuk menemukan apa persyaratan minimal untuk viewForHeaderdipanggil. Dan sekarang saya tahu. Dan sekarang Anda juga.
matt
2
@ Texas Tidak, saya tidak melakukan xamarin. Menambahkan tingkat tipuan lain di atas kerangka kerja Kakao hanya akan membuat kepalaku meledak. :)
matt
20

Memberi estimatedSectionHeaderHeightdan sectionHeaderHeightnilai - nilai memperbaiki masalah saya. misalnya, self.tableView.estimatedSectionHeaderHeight = 100 self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension

Sharukh Mastan
sumber
Masalah saya mulai setelah memutakhirkan ke Swift 3.1. Solusi ini memperbaikinya.
zevij
@pbuchheit Apple Docs mengatakan ini tersedia dari iOS 7.0+, silakan lihat di sini, developer.apple.com/documentation/uikit/uitableview/…
Sharukh Mastan
@Sharukh Mastan Sepertinya Anda benar. Untuk beberapa alasan saya mendapat peringatan ketika saya mencoba menggunakan properti itu, tetapi hilang setelah melakukan pembangunan yang bersih.
pbuchheit
7

Keluar dari jawaban rmaddy, saya mencoba menyembunyikan tampilan Header dan mengembalikan 0.0f untuk "tableView: heightForHeaderInSection" dan 0 tinggi View from tableView:viewForHeaderInSection.

Setelah berubah dari return 1.0fke return 0.0fdalam tableView:heightForHeaderInSection, metode delegasi tableView:viewForHeaderInSectionmemang dipanggil.

Ternyata efek yang saya inginkan berfungsi tanpa harus menggunakan "tableView: heightForHeaderInSection"; tetapi ini mungkin berguna bagi orang lain yang mengalami masalah mendapatkan metode delegasi "tableView: heightForHeaderInSection" yang dipanggil.

rrrrrraul
sumber
5

Anda harus menerapkan tableView:heightForHeaderInSection:dan mengatur ketinggian untuk tajuk> 0.

Metode delegasi ini sejalan dengan viewForHeaderInSection:metode tersebut.

Saya harap ini membantu.

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
         return 40;
}
Chiara
sumber
Sudahkah Anda menguji bahwa jawaban Anda benar-benar berfungsi? Karena Anda membaca dengan hati-hati maka dinyatakan bahwa awalnya viewForHeaderInSection dipanggil. Itu tidak dipanggil hanya ketika tabel dimuat ulang!
Karlis
5

Perlu dicatat secara singkat bahwa jika implementasi tableView:heightForHeaderInSection:pengembalian Anda UITableViewAutomaticDimension, maka tableView:viewForHeaderInSection:tidak akan dipanggil.

UITableViewAutomaticDimensionmengasumsikan bahwa standar UITableViewHeaderFooterViewakan digunakan yang diisi dengan metode delegasi tableView:titleForHeaderInSection:.

Dari komentar di UITableView.h:

Mengembalikan nilai ini dari tableView:heightForHeaderInSection:atau tableView:heightForFooterInSection:menghasilkan ketinggian yang sesuai dengan nilai yang dikembalikan dari tableView:titleForHeaderInSection:atau tableView:titleForFooterInSection:jika judul tidak nol.

Benjohn
sumber
1
jika Anda menetapkan estimatedSectionHeaderHeightnilai tertentu, tableView:viewForHeaderInSectionakan dipanggil (mirip dengan cara dimensi otomatis untuk baris bekerja)
GreatWiz
Menarik, terima kasih. Kembali pada 7.1 , selisih perkiraan ketinggian ini penting untuk sel , jadi mungkin juga terjadi pada header - tapi itu tidak terlalu relevan sekarang!
Benjohn
3

Saya baru saja mengalami masalah dengan tajuk yang tidak ditampilkan untuk iOS 7.1 , tetapi bekerja dengan baik dengan rilis selanjutnya yang telah saya uji, secara eksplisit dengan 8.1 dan 8.4.

Untuk kode yang sama persis, 7.1 sama sekali tidak memanggil metode delegasi header bagian, termasuk: tableView:heightForHeaderInSection:dan tableView:viewForHeaderInSection:.

Setelah bereksperimen, saya menemukan bahwa menghapus baris ini dari viewDidLoadheader buatan saya muncul kembali untuk 7.1 dan tidak memengaruhi versi lain yang saya uji:

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

... jadi, sepertinya ada semacam konflik di sana untuk 7.1, setidaknya.

Benjohn
sumber
3

Masalah yang sama terjadi dengan saya tetapi karena saya menggunakan perhitungan tinggi otomatis dari xCode 9 , saya tidak dapat memberikan nilai ketinggian yang eksplisit seperti yang disebutkan di atas. Setelah beberapa percobaan saya mendapat solusi , kita harus mengganti metode ini sebagai,

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

Meskipun saya sudah memeriksa kedua opsi

  1. Perhitungan Tinggi Otomatis
  2. Perhitungan Tinggi Perkiraan Otomatis

dari storyboard seperti kata apel, tapi tetap saja saya mendapat kesalahan aneh ini.

Harap Catatan : Kesalahan ini hanya ditampilkan pada versi IOS-10 bukan pada versi IOS-11 . Mungkin ini bug dari xCode. Terima kasih

Najam
sumber
0

Inilah yang saya temukan ( Swift 4 ) (terima kasih atas komentar ini pada pertanyaan lain)

Apakah saya menggunakan titleForHeaderInSection atau viewForHeaderInSection - bukan karena mereka tidak dipanggil ketika tampilan tabel digulir dan sel-sel baru dimuat, tetapi setiap pilihan font yang saya buat untuk headerView's textLabel hanya muncul pada apa yang awalnya terlihat pada memuat , dan tidak seperti tabel digulir.

Cara mengatasinya adalah 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)
    }
}
RanLearns
sumber
0

Dalam kasus saya, saya telah membuat tampilan tajuk menggunakan UITableviewCelldan mengembalikan sel viewForHeaderInSectionseperti ini

return cell

ubah ini menjadi

return cell.contentView 

Bekerja untukku.

pengguna1547608
sumber
0

Dalam kasus saya

viewForHeaderInSection

diimplementasikan dalam kelas turunan jauh yang tidak mengganggu untuk daisy ke kelas super.

Anton Tropashko
sumber
0

Alasan mengapa viewForHeaderInSectiontidak dipanggil adalah karena satu dari dua alasan:

Entah Anda tidak mengatur UITableViewDelegate, atau salah mengatur UITableViewDelegate.

Cem Yilmaz
sumber
0

Dalam kasus saya itu karena saya tidak menerapkan:

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
Nail Sharipov
sumber
-1

Kadang-kadang pengaturan tableview.delegateatau datasource = nildalam viewWillAppear:atau viewDidAppear:metode dapat menyebabkan masalah ini. Pastikan untuk tidak melakukan ini ...

Houzyi
sumber
-1

Saya telah memotong & menempel dua metode berikut dari proyek Swift 2 ke proyek Swift 3 saya yang tidak pernah dipanggil karena di Swift 3 metode ini harus memiliki "-" sebelum nama parameter pertama.

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
}
koira
sumber