Kustomisasi bagian tajuk UITableView

141

Saya ingin menyesuaikan UITableViewheader untuk setiap bagian. Sejauh ini, saya sudah menerapkan

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

UITabelViewDelegatemetode ini . Yang ingin saya lakukan adalah mendapatkan tajuk saat ini untuk setiap bagian dan hanya menambahkanUILabel sebagai subview.

Sejauh ini, saya tidak dapat mencapai itu. Karena, saya tidak dapat menemukan apa pun untuk mendapatkan tajuk bagian default. Pertanyaan pertama, apakah ada cara untuk mendapatkan header bagian standar ?

Jika tidak memungkinkan, saya harus membuat tampilan wadah yang merupakan UIView tetapi, kali ini saya perlu mengatur warna latar belakang default, warna bayangan dll. Karena, jika Anda melihat dengan cermat ke header bagian, itu sudah disesuaikan.

Bagaimana saya bisa mendapatkan nilai-nilai default ini untuk setiap header bagian?

Terima kasih semua.

limon
sumber
1
Apa yang salah dengan menggunakan tableView:titleForHeaderInSection:?
borrrden
Mengembalikan a NSString, saya perlu mengatur font kustom jadi, saya tidak bisa jika saya menggunakantableView:titleForHeaderInSection:
limon
Atau Anda dapat menggunakan gambar untuk meniru header bagian default. teehanlax.com/blog/ios-6-gui-psd-iphone-5
Desdenova
@limon: Bagaimana menerapkan header bagian: stackoverflow.com/a/32261262/1457385
shallowThought

Jawaban:

288

Anda dapat mencoba ini:

 -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 18)];
    /* Create custom view to display section header... */
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, tableView.frame.size.width, 18)];
    [label setFont:[UIFont boldSystemFontOfSize:12]];
     NSString *string =[list objectAtIndex:section];
    /* Section header is in 0th index... */
    [label setText:string];
    [view addSubview:label];
    [view setBackgroundColor:[UIColor colorWithRed:166/255.0 green:177/255.0 blue:186/255.0 alpha:1.0]]; //your background color...
    return view;
}
Lochana Ragupathy
sumber
Itulah warna bg Anda, apa pun warna yang ingin Anda atur
Lochana Ragupathy
Itulah masalahnya, saya sudah melakukan apa yang Anda tulis. Tapi, saya tidak tahu warna latar standar header bagian, yang agak abu-abu. Tapi, saya membutuhkannya persis header bagian default.
limon
15
hey, gunakan pengukur warna Digital
Lochana Ragupathy
pastikan untuk mengatur backgroundColor UILabel juga. Saya tahu saya sedikit bingung ketika latar belakang saya tidak menjadi jelas bagi saya.
shulmey
3
apa yang ada dalam daftar NSString * string = [list objectAtIndex: section]; siapa pun dapat memberi tahu saya
Nisha Gupta
45

Jawaban yang dipilih menggunakan tableView :viewForHeaderInSection:benar.

Hanya untuk membagikan tip di sini.

Jika Anda menggunakan storyboard / xib, maka Anda dapat membuat sel prototipe lain dan menggunakannya untuk "sel bagian" Anda. Kode untuk mengonfigurasi tajuk mirip dengan cara Anda mengonfigurasi sel baris.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    static NSString *HeaderCellIdentifier = @"Header";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:HeaderCellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:HeaderCellIdentifier];
    }

    // Configure the cell title etc
    [self configureHeaderCell:cell inSection:section];

    return cell;
}
samwize
sumber
14
ada beberapa hal yang salah dengan solusi ini. Yang pertama adalah kenyataan bahwa jika Anda menerapkan "tableView (tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool", Anda akan melihat bahwa header bagian akan bergerak bersama dengan baris ketika Anda meluncur. Untuk menghindari ini, Anda harus mengembalikan cell.contentView. Masalah yang lebih besar adalah kenyataan bahwa dengan solusi ini, aplikasi akan macet ketika Anda lama menekan bagian header. Cara yang benar adalah dengan membuat nib yang memanjang UITableViewHeaderFooterView, daftarkan dengan tableview dan kembalikan dalam metode ini. Diuji di iOS8
Kachi
@ Kachi Solusinya menggunakan viewForHeaderInSectionbukan canEditRowAtIndexPathseperti yang Anda sebutkan. Saya tidak pernah memverifikasi kerusakan yang Anda katakan, tetapi bisakah Anda mencerahkan berapa lama pers akan menyebabkan kerusakan?
samwize
1
yang saya maksudkan adalah bahwa jika Anda mengimplementasikan solusi ini DAN mengimplementasikan canEditRowAtIndexPath, Anda akan melihat bahwa header juga akan meluncur dengan dengan baris paling atas yang Anda hapus jika Anda tidak mengembalikan cell.contentView. Lihat posting SO ini: stackoverflow.com/questions/26009722/... Pers yang panjang menyebabkan crash karena pesan mencoba dikirim ke objek yang tidak dapat dialokasikan kembali. Lihat posting SO ini: stackoverflow.com/questions/27622290/…
Kachi
1
Harap jangan pernah gunakan UITableViewCellsebagai tampilan tajuk. Anda akan sangat sulit untuk men-debug gangguan visual - tajuk terkadang akan hilang karena bagaimana sel dikosongkan dan Anda akan mencari berjam-jam mengapa begitu sampai Anda menyadari UITableViewCelltidak termasuk dalam UITableViewtajuk.
raven_raven
Menggunakan UITableViewCellsebagai tajuk sama sekali salah.
Alex Zavatone
31

Versi cepat jawaban Lochana Tejas :

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRectMake(0, 0, tableView.frame.size.width, 18))
    let label = UILabel(frame: CGRectMake(10, 5, tableView.frame.size.width, 18))
    label.font = UIFont.systemFontOfSize(14)
    label.text = list.objectAtIndex(indexPath.row) as! String
    view.addSubview(label)
    view.backgroundColor = UIColor.grayColor() // Set your background color

    return view
}
estemendoza
sumber
1
bagaimana cara membuat tinggi label dinamis sesuai teks yang ada di dalam tampilan?
Pratik Shah
Kata overridekunci tersebut berlebihan. Terlebih lagi, pertimbangkan untuk menggunakan kembali tampilan tajuk daripada membuatnya kembali.
Vadim Bulavin
17

Jika Anda menggunakan tampilan tajuk default, Anda hanya dapat mengubah teks dengannya

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

Untuk Swift:

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

Jika Anda ingin menyesuaikan tampilan, Anda perlu membuat yang baru sendiri.

Mert
sumber
10

mengapa tidak menggunakan UITableViewHeaderFooterView ?

pengguna836773
sumber
Anda hanya dapat menggunakan ini jika Anda tidak menggunakan - (UIView *) tableView: (UITableView *) tableView viewForHeaderInSection: (NSInteger) bagian.
SAHM
1
Jawaban yang benar-benar valid. Juga, menggunakan manfaat UITableViewHeaderFooterView dari tampilan daur ulang seperti halnya sel.
Gregzo
6
@dmarsi saya tidak menemukan bukti bahwa mereka sudah usang.
Fawkes
8

Jika headerInSection tidak ditampilkan, dapat mencoba ini.

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

Ini mengembalikan ketinggian untuk tajuk bagian tertentu.

Kathen
sumber
1
Pikiran menguraikan jawaban Anda?
CinCout
Bagian header tidak akan ditampilkan kecuali jika Anda menentukan dengan metode kait 'tinggi' dari header bagian. Default UITableView untuk tidak menampilkan header jika tidak ada ketinggian yang ditentukan. @CinCout
theprojectabot
6

Swift 3 versi jawaban lochana dan estemendoza:

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

    let view = UIView(frame: CGRect(x:0, y:0, width:tableView.frame.size.width, height:18))
    let label = UILabel(frame: CGRect(x:10, y:5, width:tableView.frame.size.width, height:18))
    label.font = UIFont.systemFont(ofSize: 14)
    label.text = "This is a test";
    view.addSubview(label);
    view.backgroundColor = UIColor.gray;
    return view

}

Perlu diketahui juga bahwa Anda JUGA harus menerapkan:

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 100;
}
Adam
sumber
5

Coba ini......

override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) 
{
    // Background view is at index 0, content view at index 1
    if let bgView = view.subviews[0] as? UIView
    {
        // do your stuff
    }

    view.layer.borderColor = UIColor.magentaColor().CGColor
    view.layer.borderWidth = 1
}
Gigi
sumber
5

Jawaban lain melakukan pekerjaan yang baik untuk menciptakan kembali tampilan header default, tetapi tidak benar-benar menjawab pertanyaan utama Anda:

apakah ada cara untuk mendapatkan header bagian standar?

Ada cara - hanya menerapkan tableView:willDisplayHeaderView:forSection:di delegasi Anda. Tampilan tajuk default akan diteruskan ke parameter kedua, dan dari sana Anda dapat melemparkannya ke a UITableViewHeaderFooterViewdan kemudian menambahkan / mengubah subview sesuai keinginan.

Obj-C

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    UITableViewHeaderFooterView *headerView = (UITableViewHeaderFooterView *)view;

    // Do whatever with the header view... e.g.
    // headerView.textLabel.textColor = [UIColor whiteColor]
}

Cepat

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
{
    let headerView = view as! UITableViewHeaderFooterView

    // Do whatever with the header view... e.g.
    // headerView.textLabel?.textColor = UIColor.white
}
Craig Brown
sumber
Anda tidak perlu membuangnya. Anda bisa menambahkan apa yang Anda inginkan ke tampilan. Bahkan, membuat objek baru tidak akan melakukan apa pun kecuali Anda menugaskannya view.
Alex Zavatone
@AlexZavatone Benar, Anda tidak perlu menampilkannya jika Anda hanya menambahkan tampilan. Akan membantu jika Anda ingin menyesuaikan beberapa tampilan default seperti label teks.
Craig Brown
4
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    //put your values, this is part of my code
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 30.0f)];
    [view setBackgroundColor:[UIColor redColor]];
    UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, 150, 20)];
    [lbl setFont:[UIFont systemFontOfSize:18]];
    [lbl setTextColor:[UIColor blueColor]];
    [view addSubview:lbl];

    [lbl setText:[NSString stringWithFormat:@"Section: %ld",(long)section]];

    return view;
}
Boris Nikolic
sumber
4

Ini adalah solusi termudah yang mungkin. Kode berikut dapat digunakan secara langsung untuk membuat header bagian kustom.

 -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    SectionHeaderTableViewCell *headerView = [tableView dequeueReusableCellWithIdentifier:@"sectionHeader"];

    //For creating a drop menu of rows from the section
    //==THIS IS JUST AN EXAMPLE. YOU CAN REMOVE THIS IF-ELSE.==
    if (![self.sectionCollapsedArray[section] boolValue])
    {
        headerView.imageView.image = [UIImage imageNamed:@"up_icon"];
    }
    else
    {
        headerView.imageView.image = [UIImage imageNamed:@"drop_icon"];
    }

    //For button action inside the custom cell
    headerView.dropButton.tag = section;
    [headerView.dropButton addTarget:self action:@selector(sectionTapped:) forControlEvents:UIControlEventTouchUpInside];

    //For removing long touch gestures.
    for (UIGestureRecognizer *recognizer in headerView.contentView.gestureRecognizers)
    {
        [headerView.contentView removeGestureRecognizer:recognizer];
        [headerView removeGestureRecognizer:recognizer];
    }

    return headerView.contentView;
}

CATATAN: SectionHeaderTableViewCell adalah UITableViewCell khusus yang dibuat di Storyboard.

Anish Kumar
sumber
SectionHeaderTableViewCell - penggunaan pengidentifikasi yang tidak diumumkan
Boris Gafurov
@BorisGafurov SectionHeaderTableViewCell hanyalah sebuah contoh nama yang saya berikan kepada UITableViewCell saya, yang saya buat di storyboard.
Anish Kumar
2

Jika saya jadi Anda, saya akan membuat metode yang mengembalikan UIView diberi NSString untuk mengandung. Sebagai contoh

+ (UIView *) sectionViewWithTitle:(NSString *)title;

Dalam implementasi metode ini, buat UIView, tambahkan label UIL ke dalamnya dengan properti yang ingin Anda atur, dan tentu saja tentukan judulnya untuk yang diberikan.

cpprulez
sumber
Ya, saya bisa melakukan itu, tetapi pertanyaan saya adalah bagaimana saya bisa mendapatkan latar belakang header bagian default, nilai bayangan, sisanya mudah diimplementasikan.
limon
apa yang Anda maksud dengan latar belakang header bagian default
Lochana Ragupathy
1
Nah, yang termudah adalah dengan menggunakan aplikasi Digital Color Meter untuk mendapatkan warna yang Anda inginkan. Membawa mereka dengan kode akan sulit, sejauh yang saya tahu ...
cpprulez
2

solusi @ samwize di Swift (jadi upvote dia!). Brilliant menggunakan mekanisme daur ulang yang sama juga untuk bagian header / footer:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let settingsHeaderSectionCell:SettingsHeaderSectionCell = self.dequeueReusableCell(withIdentifier: "SettingsHeaderSectionCell") as! SettingsHeaderSectionCell

    return settingsHeaderSectionCell
}
Javier Calatrava Llavería
sumber
2
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
    if([view isKindOfClass:[UITableViewHeaderFooterView class]]){

        UITableViewHeaderFooterView *headerView = view;

        [[headerView textLabel] setTextColor:[UIColor colorWithHexString:@"666666"]];
        [[headerView textLabel] setFont:[UIFont fontWithName:@"fontname" size:10]];
    }
}

Jika Anda ingin mengubah font dari textLabel di bagian header Anda, Anda ingin melakukannya di willDisplayHeaderView. Untuk mengatur teks, Anda dapat melakukannya di viewForHeaderInSection atau titleForHeaderInSection. Semoga berhasil!

John Ottenlips
sumber
2

Contoh 2019 lengkap untuk menyalin dan menempel

Set pertama "Dikelompokkan" di storyboard: itu harus terjadi pada waktu init, Anda tidak dapat benar-benar mengaturnya nanti, jadi lebih mudah untuk mengingatnya di storyboard:

masukkan deskripsi gambar di sini

Lanjut,

Harus menerapkan heightForHeaderInSection karena bug Apple.

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

Masih ada bug Apple - selama sepuluh tahun sekarang - di mana ia tidak akan menampilkan header pertama (yaitu, indeks 0) jika Anda tidak memiliki heightForHeaderInSection panggilan.

Jadi, tableView.sectionHeaderHeight = 70tidak berfungsi, itu rusak .

Mengatur bingkai tidak menghasilkan apa-apa:

Di viewForHeaderInSection cukup membuat UIView ().

Tidak ada gunanya / mencapai apa-apa jika Anda UIView (bingkai ...) karena iOS hanya menetapkan ukuran tampilan yang ditentukan oleh tabel.

Jadi baris pertama viewForHeaderInSectionakan sederhana let view = UIView()dan itu adalah tampilan yang Anda kembalikan.

func tableView(_ tableView: UITableView,
                       viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView()
    
    let l = UILabel()
    view.addSubview(l)
    l.bindEdgesToSuperview()
    l.backgroundColor = .systemOrange
    l.font = UIFont.systemFont(ofSize: 15)
    l.textColor = .yourClientsFavoriteColor
    
    switch section {
    case 0:
        l.text =  "First section on screen"
    case 1:
        l.text =  "Here's the second section"
    default:
        l.text =  ""
    }
    
    return view
}

Itu saja - hal lain adalah pemborosan waktu.

Masalah Apple "rewel" lainnya.


Ekstensi kenyamanan yang digunakan di atas adalah:

extension UIView {
    
    // incredibly useful:
    
    func bindEdgesToSuperview() {
        
        guard let s = superview else {
            preconditionFailure("`superview` nil in bindEdgesToSuperview")
        }
        
        translatesAutoresizingMaskIntoConstraints = false
        leadingAnchor.constraint(equalTo: s.leadingAnchor).isActive = true
        trailingAnchor.constraint(equalTo: s.trailingAnchor).isActive = true
        topAnchor.constraint(equalTo: s.topAnchor).isActive = true
        bottomAnchor.constraint(equalTo: s.bottomAnchor).isActive = true
    }
}
Fattie
sumber
1

Secara ajaib tambahkan Table View Header dengan cepat

Baru-baru ini saya mencoba ini.

Saya membutuhkan satu dan hanya satu header di seluruh UITableView.

Seperti saya menginginkan UIImageView di bagian atas TableView. Jadi saya menambahkan UIImageView di atas UITableViewCell dan secara otomatis ditambahkan sebagai tableViewHeader. Sekarang saya menghubungkan ImageView ke ViewController dan menambahkan Image.

Saya bingung karena saya melakukan sesuatu seperti ini untuk pertama kalinya. Jadi untuk menghapus kebingungan saya, buka format xml dari MainStoryBoard dan temukan Image View ditambahkan sebagai header.

Ini berhasil untuk saya. Terima kasih xCode dan cepat.

Somir Saikia
sumber
1

panggil metode delegasi ini

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

return @"Some Title";
}

ini akan memberi kesempatan untuk secara otomatis menambahkan header default dengan judul dinamis.

Anda dapat menggunakan header / footer yang dapat digunakan kembali dan dapat disesuaikan.

https://github.com/sourov2008/UITableViewCustomHeaderFooterSection

Shourob Datta
sumber
1

swif 4.2

override func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }

    header.textLabel?.textAlignment = .center // for all sections

    switch section {
    case 1:  //only section No.1
        header.textLabel?.textColor = .black
    case 3:  //only section No.3
        header.textLabel?.textColor = .red
    default: //
        header.textLabel?.textColor = .yellow
    }
}
flowGlen
sumber
0

Jika Anda hanya ingin menambahkan judul ke header tableView jangan tambahkan tampilan. Di swift 3.x kodenya seperti ini:

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    var lblStr = ""
    if section == 0 {
        lblStr = "Some String 1"
    }
    else if section == 1{
        lblStr = "Some String 2"
    }
    else{
        lblStr = "Some String 3"
    }
    return lblStr
}

Anda dapat menerapkan array untuk mengambil judul untuk header.

abhishek chakrabartti
sumber
0

Kembali ke pertanyaan awal (4 tahun kemudian), alih-alih membangun kembali tajuk bagian Anda sendiri, iOS dapat langsung memanggil Anda (dengan willDisplayHeaderView: forSection :) tepat setelah dibuat yang standar. Misalnya, saya ingin menambahkan tombol grafik di tepi kanan header bagian:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
    UITableViewHeaderFooterView * header = (UITableViewHeaderFooterView *) view;
    if (header.contentView.subviews.count >  0) return; //in case of reuse
    CGFloat rightEdge = CGRectGetMaxX(header.contentView.bounds);
    UIButton * button = [[UIButton alloc] initWithFrame:CGRectMake(rightEdge - 44, 0, 44, CGRectGetMaxY(header.contentView.bounds))];
    [button setBackgroundImage:[UIImage imageNamed:@"graphIcon"] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(graphButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [view addSubview:button];
}
Mackworth
sumber
0

Gunakan tableView: willDisplayHeaderView:untuk menyesuaikan tampilan ketika akan ditampilkan.

Ini memberi Anda keuntungan karena dapat mengambil tampilan yang sudah dibuat untuk tampilan header dan memperluasnya, daripada harus membuat ulang seluruh tampilan header sendiri.

Berikut adalah contoh yang mewarnai bagian header berdasarkan BOOL dan menambahkan elemen teks detail ke header.

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
//    view.tintColor = [UIColor colorWithWhite:0.825 alpha:1.0]; // gray
//    view.tintColor = [UIColor colorWithRed:0.825 green:0.725 blue:0.725 alpha:1.0]; // reddish
//    view.tintColor = [UIColor colorWithRed:0.925 green:0.725 blue:0.725 alpha:1.0]; // pink

    // Conditionally tint the header view
    BOOL isMyThingOnOrOff = [self isMyThingOnOrOff];

    if (isMyThingOnOrOff) {
        view.tintColor = [UIColor colorWithRed:0.725 green:0.925 blue:0.725 alpha:1.0];
    } else {
        view.tintColor = [UIColor colorWithRed:0.925 green:0.725 blue:0.725 alpha:1.0];
    }

    /* Add a detail text label (which has its own view to the section header… */
    CGFloat xOrigin = 100; // arbitrary
    CGFloat hInset = 20;
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(xOrigin + hInset, 5, tableView.frame.size.width - xOrigin - (hInset * 2), 22)];

    label.textAlignment = NSTextAlignmentRight;

    [label setFont:[UIFont fontWithName:@"Helvetica-Bold" size:14.0]
    label.text = @"Hi.  I'm the detail text";

    [view addSubview:label];
}
Alex Zavatone
sumber
0

Cepat 4.2

Dalam Swift 4.2 nama tabel sedikit berubah.

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 18))
        let label = UILabel(frame: CGRect(x: 10, y: 5, width: tableView.frame.size.width, height: 18))
        label.font = UIFont.systemFont(ofSize: 14)
        label.text = list.objectAtIndex(section) as! String
        view.addSubview(label)
        view.backgroundColor = UIColor.gray // Set your background color

        return view
    }
Esmaeil
sumber