UITableView üstbilgi bölümünü özelleştir


141

UITableViewHer bölüm için başlığı özelleştirmek istiyorum . Şimdiye kadar uyguladım

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

bu UITabelViewDelegateyöntem. Ne yapmak istiyorum her bölüm için geçerli üstbilgi almak ve sadece UILabelbir alt görünüm olarak eklemek .

Şimdiye kadar bunu başaramıyorum. Çünkü, varsayılan bölüm üstbilgisini almak için hiçbir şey bulamadım. İlk soru, varsayılan bölüm üstbilgisini almanın herhangi bir yolu var mı?

Mümkün değilse, bir kapsayıcı görünümü oluşturmam gerekiyor, UIViewancak bu sefer varsayılan arka plan rengini, gölge rengini vb. Ayarlamam gerekiyor.

Her bölüm üstbilgisi için bu varsayılan değerleri nasıl alabilirim?

Hepinize teşekkür ederim.


1
Kullanmanın nesi yanlış tableView:titleForHeaderInSection:?
borrrden

Döndürür NSString, özel yazı tipi ayarlamam gerekiyor, bu yüzden kullanamamtableView:titleForHeaderInSection:
limon

Veya varsayılan bölüm başlıklarını taklit etmek için görüntüleri kullanabilirsiniz. teehanlax.com/blog/ios-6-gui-psd-iphone-5
Desdenova

@limon: Bölüm başlığı nasıl uygulanır: stackoverflow.com/a/32261262/1457385
shallowThought

Yanıtlar:


288

Bunu deneyebilirsiniz:

 -(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;
}

ayarlamak için istediğiniz bg renk watever renk yapabilirsiniz
Lochana Ragupathy

Sorun bu, yazdıklarını zaten yaptım. Ancak, bölüm başlığının varsayılan arka plan rengini bilmiyorum, ki bu biraz gri. Ancak, tam olarak varsayılan bölüm başlığı olması gerekiyor.
limon

15
hey hadi kullanım Dijital renk ölçer
Lochana Ragupathy

UILabel'ın backgroundColor ayarını da yaptığınızdan emin olun. Arka planım benim için netleşmediğinde biraz kafam karıştığını biliyorum.
shulmey

3
NSString satırındaki liste nedir * string = [list objectAtIndex: section]; Herkes bana söyleyebilir
Nisha Gupta

45

Seçilen cevap tableView :viewForHeaderInSection:doğru.

Burada bir ipucu paylaşmak için.

Film şeridi / xib kullanıyorsanız, başka bir prototip hücre oluşturabilir ve bunu "bölüm hücreniz" için kullanabilirsiniz. Üstbilgiyi yapılandırmak için kullanılan kod, satır hücreleri için nasıl yapılandırdığınıza benzer.

- (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;
}

14
bu çözümde yanlış olan birkaç şey var. Bunlardan birincisi, "tableView (tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool" komutunu uygularsanız, slayt üstbilgisinin kaydırdığınızda satırla birlikte hareket edeceğini fark edersiniz. Bundan kaçınmak için bunun yerine cell.contentView öğesini döndürmelisiniz. Büyük sorun, bu çözümle, bölüm başlığına uzun bastığınızda uygulamanın çökmesi gerçeğidir. Doğru yol, UITableViewHeaderFooterView'ı genişleten bir uç oluşturmak, tablo görünümü ile kaydettirmek ve bu yöntemde döndürmektir. İOS8'de test edildi
Kachi

@Kachi çözüm kullanıyor viewForHeaderInSectiondeğil canEditRowAtIndexPathbahsettiğin gibi. Söylediğin kazayı asla doğrulamam, ama uzun bir basışın kazaya nasıl sebep olacağını aydınlatabilir misin?
samwize

1
Demek istediğim, bu çözümü uygularsanız ve canEditRowAtIndexPath'i uygularsanız, üstbilginin cell.contentView döndürmezseniz sildiğiniz en üst satırla da kayacağını göreceksiniz. Bkz. SO post: stackoverflow.com/questions/26009722/… Bir mesaj, ayrılmış bir nesneye gönderilmeye çalıştığından uzun basış çökmeye neden oluyor. Bu SO yayınına bakın: stackoverflow.com/questions/27622290/…
Kachi

1
Lütfen hiçbir zaman UITableViewCellbaşlık görünümü olarak kullanmayın . Görsel aksaklıkların hatalarını ayıklamak çok zor olacak - üstbilgi bazen hücrelerin nasıl ayıklandığından dolayı kaybolacak ve saatlerce bakacaksınız ki UITableViewCell, UITableViewbaşlığa ait olmadığını fark edene kadar .
raven_raven

UITableViewCellA başlık olarak kullanmak yanlıştır.
Alex Zavatone

31

Lochana Tejas'ın hızlı versiyonu cevap:

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
}

1
görünümün içindeki metne göre etiket yüksekliğini nasıl dinamik hale getirebilirim?
Pratik Şah

overrideAnahtar kelime gereksizdir. Dahası, başlık görünümlerini yeniden oluşturmak yerine yeniden kullanmayı düşünün.
Vadim Bulavin

17

Varsayılan başlık görünümünü kullanıyorsanız, üzerindeki metni yalnızca

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

Swift için:

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

Görünümü özelleştirmek istiyorsanız, kendiniz için yeni bir görünüm oluşturmanız gerekir.


10

neden UITableViewHeaderFooterView kullanmıyorsunuz ?


Bunu yalnızca - (UIView *) tableView: (UITableView *) tableView viewForHeaderInSection: (NSInteger) bölümünü de kullanmazsanız kullanabilirsiniz.
SAHM

1
Mükemmel geçerli cevap. Ayrıca, UITableViewHeaderFooterView kullanımı, tıpkı hücreler gibi görünüm geri dönüşümünden yararlanır.
Gregzo

6
@ dmarsi Onların onaylanmadığına dair hiçbir kanıt bulamadım.
Fawkes

8

HeaderInSection gösterilmiyorsa bunu deneyebilirsiniz.

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

Bu, belirli bir bölümün başlığı için bir yükseklik döndürür.


1
Cevabınızı ayrıntıya sokmak ister misiniz?
CinCout

Üstbilgi bölümü, bölüm üstbilgisinin 'yüksekliğini' bir yöntemle belirtmedikçe gösterilmez. Yükseklik belirtilmezse, UITableView varsayılan olarak üstbilgileri göstermez. @CinCout
theprojectabot

6

Lochana ve estemendoza'nın hızlı 3 versiyonu cevaplar:

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

}

Ayrıca, şunları da uygulamanız gerektiğini unutmayın:

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

5

Bunu dene......

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
}

5

Diğer cevaplar, varsayılan başlık görünümünü yeniden oluşturma konusunda iyi bir iş çıkarır, ancak aslında ana sorunuza cevap vermeyin:

varsayılan bölüm üstbilgisini almanın herhangi bir yolu var mı?

Bir yol var - sadece tableView:willDisplayHeaderView:forSection:temsilcinize uygulayın. Varsayılan başlık görünümü ikinci parametreye aktarılacak ve oradan bir UITableViewHeaderFooterViewa'ya aktarabilir ve ardından istediğiniz gibi alt görünümler ekleyebilir / değiştirebilirsiniz.

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]
}

hızlı

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
}

Onu yayınlamanıza gerek yok. Sadece görünüme istediğinizi ekleyebilirsiniz. Aslında, yeni bir nesne oluşturmak, ona atamadığınız sürece hiçbir şey yapmaz view.
Alex Zavatone

@AlexZavatone Doğru, yalnızca görünüm ekliyorsanız yayınlamanıza gerek yok. Metin etiketi gibi bazı varsayılan görünümleri özelleştirmek istiyorsanız faydalıdır.
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;
}

4

Bu mümkün olan en kolay çözümdür. Aşağıdaki kod, doğrudan özel bir bölüm başlığı oluşturmak için kullanılabilir.

 -(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;
}

NOT: SectionHeaderTableViewCell, Storyboard'da oluşturulan özel bir UITableViewCell'dir.


SectionHeaderTableViewCell - bildirilmemiş tanımlayıcı kullanımı
Boris Gafurov

@BorisGafurov SectionHeaderTableViewCell, film şeridinde oluşturduğum UITableViewCell'imi verdiğim örnek bir isim.
Anish Kumar

2

Ben olsaydım, içermek için bir NSString verilen bir UIView döndüren bir yöntem yapardı. Örneğin

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

Bu yöntemin uygulanmasında bir UIView oluşturun, ayarlamak istediğiniz özelliklere sahip bir UILabel ekleyin ve elbette başlığını verilene ayarlayın.


Evet, bunu yapabilirim, ama benim sorum nasıl varsayılan bölüm üstbilgi arka planı, gölge değeri alabilirim, gerisini uygulamak kolaydır.
limon

varsayılan bölüm başlığı arka planı ile ne demek istiyorsun
Lochana Ragupathy

1
En kolayı, istediğiniz renkleri elde etmek için Dijital Renk Ölçer uygulamasını kullanmak olacaktır. Onları kodla almak zor, anlayabildiğim kadarıyla ...
cpprulez

2

@ samwize'in Swift'teki çözümü (bu yüzden onu oyla!). Üstbilgi / altbilgi bölümleri için de aynı geri dönüşüm mekanizmasını kullanarak mükemmel:

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

    return settingsHeaderSectionCell
}

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]];
    }
}

Bölüm başlığınızdaki textLabel yazı tipini değiştirmek istiyorsanız, bunu willDisplayHeaderView içinde yapmak istersiniz. Metni ayarlamak için metni viewForHeaderInSection veya titleForHeaderInSection içinde yapabilirsiniz. İyi şanslar!


2

Kopyalamak ve yapıştırmak için tam 2019 örneği

Film şeridinde ilk olarak "Gruplandırılmış" olarak ayarlayın: başlangıçta gerçekleşmelidir, daha sonra gerçekten ayarlayamazsınız, bu yüzden film şeridinde yapmayı hatırlamak daha kolaydır:

resim açıklamasını buraya girin

Sonraki,

Must uygulamak heightForHeaderInSection nedeniyle Elma hatadan.

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

Hala bir Apple hatası var - on yıldır - heightForHeaderInSectionaramanız yoksa ilk üstbilgiyi (yani, dizin 0) göstermeyecek .

Yani, tableView.sectionHeaderHeight = 70işe yaramıyor, kırılmış .

Bir çerçeve ayarlamak hiçbir şey yapmaz:

Gelen viewForHeaderInSectionbasitçe bir UIView oluşturmak ().

İOS basitçe tablonun belirlediği şekilde görünümün boyutunu ayarladığından anlamsızdır / UIView (çerçeve ...) yaparsanız hiçbir şey elde edemez .

Yani ilk satır viewForHeaderInSectionbasit olacak let view = UIView()ve geri döndüğünüz görünüm bu.

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
}

Hepsi bu kadar - her şey zaman kaybı.

Başka bir "telaşlı" Apple sorunu.


Yukarıda kullanılan kolaylık uzantısı:

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

1

Tablo Görünümü Üstbilgisini sihirli bir şekilde hızlıca ekleyin

Son zamanlarda bunu denedim.

Bütün UITableView bir ve sadece bir başlık gerekiyordu.

TableView üst kısmında bir UIImageView istedim gibi. Bu yüzden UITableViewCell üstüne bir UIImageView ekledim ve otomatik olarak bir tableViewHeader olarak eklendi. Şimdi ImageView ViewController bağlamak ve görüntü ekledi.

Kafam karıştı çünkü ilk defa böyle bir şey yaptım. Bu yüzden karışıklığımı temizlemek için MainStoryBoard'un xml formatını açın ve Resim Görünümü'nün başlık olarak eklendiğini gördüm.

Benim için çalıştı. Teşekkürler xCode ve swift.



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


0

Sadece tabloya başlık eklemek istiyorsanız, Görünüm başlığı bir görünüm eklemeyin. Swift 3.x'de kod şöyle gider:

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
}

Üstbilgilerin başlığını getirmek için bir dizi uygulayabilirsiniz.


0

Orijinal bölüme (4 yıl sonra) geri dönüp, kendi bölüm başlığınızı yeniden oluşturmak yerine iOS, varsayılanı oluşturduktan hemen sonra sizi arayacak (willDisplayHeaderView: forSection :) ile. Örneğin, bölüm üstbilgisinin sağ kenarına bir grafik düğmesi eklemek istedim:

- (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];
}

0

tableView: willDisplayHeaderView:Görüntülenmek üzere olduğunda görünümü özelleştirmek için kullanın .

Bu, tüm üstbilgi görünümünü kendiniz yeniden oluşturmak yerine, üstbilgi görünümü için önceden oluşturulmuş görünümü alıp genişletebilmenizi sağlar.

Başlık bölümünü bir BOOL'a göre renklendiren ve başlığa bir ayrıntı metin öğesi ekleyen bir örnek aşağıdadır.

- (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];
}

0

Hızlı 4.2

Swift 4.2'de tablonun adı biraz değişti.

    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
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.