自定义UITableView标头部分


141

我想UITableView为每个部分自定义标题。到目前为止,我已经实施了

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

这种UITabelViewDelegate方法。我想要做的是获取每个部分的当前标题,然后将其添加UILabel为子视图。

到目前为止,我还无法完成。因为,我找不到任何东西来获取默认节头。第一个问题,有什么方法可以获取默认节头

如果不可能,那么我需要创建一个容器视图UIView,但这一次,我需要设置默认的背景颜色,阴影颜色等。因为,如果仔细查看节的标题,它已经被自定义了。

如何获取每个节标题的这些默认值?

谢谢你们。


1
使用有什么问题tableView:titleForHeaderInSection:
borrrden

它返回一个NSString,我需要设置自定义字体,所以,如果使用我就无法设置tableView:titleForHeaderInSection:
limon

或者,您可以使用图像来模仿默认的节标题。teehanlax.com/blog/ios-6-gui-psd-iphone-5
Desdenova

Answers:


288

您可以尝试以下方法:

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

多数民众赞成在您要设置的bg颜色watever颜色
Lochana Ragupathy

这就是问题,我已经完成了您所写的内容。但是,我不知道节标题的默认背景颜色是灰色。但是,我需要它完全是默认的节头。
柠檬

15
嘿,开始使用数字色度计
Lochana Ragupathy

确保同时设置UILabel的backgroundColor。我知道当我的背景不清楚时,我有些困惑。
shulmey

3
NSString行中的列表是什么* string = [list objectAtIndex:section]; 谁能告诉我
Nisha Gupta 2015年

45

选择的答案使用tableView :viewForHeaderInSection:正确。

只是在这里分享一个提示。

如果您正在使用情节提要/ xib,则可以创建另一个原型单元并将其用于“分区”。配置标头的代码与配置行单元格的方式相似。

- (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
此解决方案有很多问题。首先是以下事实:如果实现“ tableView(tableView:UITableView,canEditRowAtIndexPath indexPath:NSIndexPath)-> Bool”,则会注意到部分标题将在滑动时与行一起移动。为避免这种情况,您必须改为返回cell.contentView。更大的问题是,使用此解决方案,当您长按节标题时,应用程序将崩溃。正确的方法是创建一个扩展UITableViewHeaderFooterView的笔尖,并使用表视图对其进行注册,然后在此方法中将其返回。测试在iOS8上
Kachi

@Kachi解决方案的使用与您提到的viewForHeaderInSectioncanEditRowAtIndexPath一样。我从不核实您所说的崩溃,但是您能启发一下长按会导致崩溃吗?
samwize 2015年

1
我的意思是,如果实施此解决方案并实施canEditRowAtIndexPath,您将看到,如果不返回cell.contentView,则标头也会与要删除的最上面的行一起滑动。请参阅此SO帖子:stackoverflow.com/questions/26009722/… 长按会导致崩溃,因为消息试图发送到已释放的对象。看到这样的帖子:stackoverflow.com/questions/27622290/…–
Kachi

1
请永远不要UITableViewCell用作标题视图。您将很难调试视觉故障-由于单元出队的方式,报头有时会消失,并且您将花几个小时寻找原因,直到您意识到UITableViewCell不属于UITableView报头。
raven_raven

使用a UITableViewCell作为标题是完全错误的。
亚历克斯·扎瓦通

31

Swift版本的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
}

1
如何根据视图中的文本使标签高度动态变化?
Pratik Shah

override关键字是多余的。此外,考虑重用标题视图而不是重新创建它们。
Vadim Bulavin

17

如果使用默认标题视图,则只能使用

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

对于Swift:

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

如果要自定义视图,则需要自己创建一个新视图。


10

为什么不使用UITableViewHeaderFooterView


仅当不同时使用-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)部分时,才可以使用此方法。
SAHM 2013年

1
完全有效的答案。同样,使用UITableViewHeaderFooterView可以像单元格一样从视图回收中受益。
Gregzo 2014年

6
@dmarsi我发现没有证据表明它们已被弃用。
福克斯2015年

8

如果未显示headerInSection,可以尝试此操作。

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

这将返回给定节的标题的高度。


1
介意您的答案吗?
CinCout

除非您使用方法指定钩住部分标题的“高度”,否则标题部分不会显示。如果未指定高度,则UITableView默认不显示标题。@CinCout
theprojectabot

6

Swift 3版本的lochana和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

}

另外,还建议您还必须实现:

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

5

试试这个......

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

其他答案在重新创建默认标题视图方面做得很好,但实际上并没有回答您的主要问题:

有什么办法来获取默认的节头?

有一种方法-只需tableView:willDisplayHeaderView:forSection:在您的代表中实施即可。默认的标题视图将传递到第二个参数中,然后您可以将其转换为a UITableViewHeaderFooterView,然后根据需要添加/更改子视图。

对象

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

迅速

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
}

您无需强制转换。您可以仅将所需内容添加到视图中。实际上,创建新对象不会执行任何操作,除非您将其分配给view
Alex Zavatone '17

@AlexZavatone是的,如果您只是添加视图,则不需要强制转换。如果要自定义一些默认视图(例如文本标签),这将很有帮助。
克雷格·布朗 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

这是最简单的解决方案。以下代码可以直接用于创建自定义节标题。

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

注意:SectionHeaderTableViewCell是在情节提要中创建的自定义UITableViewCell。


SectionHeaderTableViewCell-使用未声明的标识符
Boris Gafurov

@BorisGafurov SectionHeaderTableViewCell只是我给我的UITableViewCell命名的一个示例名称,该名称是我在情节提要中创建的。
阿尼丝·库玛

2

如果我是你,我将创建一个方法,该方法返回给定要包含NSString的UIView。例如

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

在此方法的实现中,创建一个UIView,将UILabel添加到要设置的属性,然后将其标题设置为给定的属性。


是的,我可以这样做,但是我的问题是如何获取默认的节标题背景,阴影值,其余的易于实现。
柠檬

默认情况下,节标题背景是什么意思
Lochana Ragupathy

1
好吧,最简单的方法是使用Digital Color Meter应用程序获取所需的颜色。据我所知,将它们作为代码将非常困难……
cpprulez 2013年

2

@samwize在Swift中的解决方案(所以赞他!)。在页眉/页脚部分也使用相同的回收机制:

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

如果要更改节标题中的textLabel字体,请在willDisplayHeaderView中进行更改。要设置文本,可以在viewForHeaderInSection或titleForHeaderInSection中进行设置。祝好运!


2

完整的2019年示例要复制和粘贴

首先在情节提要上设置“分组”:它必须在初始化时发生,您以后不能真正进行设置,因此更容易记住在情节提要上进行设置:

在此处输入图片说明

下一个,

由于Apple错误,必须实现heightForHeaderInSection

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

至今已有十年之久的Apple漏洞-如果您没有heightForHeaderInSection通话,它根本不会显示第一个标题(即索引0)。

所以,tableView.sectionHeaderHeight = 70根本不起作用,它坏了

设置框架没有任何效果:

viewForHeaderInSection简单地创建一个UIView()。

这是毫无意义的/ 实现什么,如果你的UIView(帧...)因为iOS只是根据表确定设置视图的大小。

因此,第一行将viewForHeaderInSection很简单let view = UIView(),这就是您返回的视图。

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
}

就是这样-其他任何事情都是浪费时间。

苹果公司的另一个“麻烦”问题。


上面使用的便捷扩展是:

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

快速添加表格视图标题

最近我尝试了这个。

在整个UITableView中,我只需要一个标头。

就像我想要在TableView顶部的UIImageView一样。因此,我在UITableViewCell的顶部添加了一个UIImageView,并自动将其作为tableViewHeader添加。现在,我将ImageView连接到ViewController并添加了Image。

我很困惑,因为我是第一次做这样的事情。因此,为了消除混乱,请打开MainStoryBoard的xml格式,并发现将Image View添加为标题。

它为我工作。感谢xCode和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

如果您只是想向tableView标头添加标题,请不要添加视图。在Swift 3.x中,代码如下所示:

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
}

您可以实现一个数组以获取标题的标题。


0

回到最初的问题(4年后),而不是重建您自己的节标题,iOS可以在构建默认问题后立即调用您(使用willDisplayHeaderView:forSection :)。例如,我想在部分标题的右侧添加一个图形按钮:

- (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:自定义视图,当它即将被显示。

这给您带来的优势是,能够采用已经为标题视图创建的视图并将其扩展,而不必自己重新创建整个标题视图。

这是一个基于BOOL为标题部分着色并向标题添加细节文本元素的示例。

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

斯威夫特4.2

在Swift 4.2中,表的名称有所更改。

    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
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.