ios – 在Interface Builder中设计UITableView的section标题

我有一个带有UITableView的xib文件,我想使用委托方法tableView:viewForHeaderInSection:添加一个自定义的部分标题视图.有没有可能在Interface Builder中设计它,然后以编程方式更改其中的一些子视图的属性?

我的UITableView具有更多的部分标题,因此在Interface Builder中创建一个UIView并返回它不起作用,因为我必须复制它,但没有任何好的方法.归档和取消归档它对于UIImages不起作用,所以UIImageViews将显示空白.

此外,我不想以编程方式创建它们,因为它们太复杂,并且生成的代码将难以阅读和维护.

编辑1:对于那些还不明白的人,真的需要一些无用的代码来理解它,这里是我的tableView:viewForHeaderInSection:方法:

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

    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    }

    CGSize headerSize = CGSizeMake(self.view.frame.size.width,100);

    /* wrapper */

    UIView *wrapperView = [UIView viewWithSize:headerSize];

    wrapperView.backgroundColor = [UIColor colorWithHexString:@"2670ce"];

    /* title */

    CGPoint titleMargin = CGPointMake(15,8);

    UILabel *titleLabel = [UILabel labelWithText:self.categoriesNames[section] andFrame:CGEasyRectMake(titleMargin,CGSizeMake(headerSize.width - titleMargin.x * 2,20))];

    titleLabel.textColor = [UIColor whiteColor];
    titleLabel.font = [UIFont fontWithStyle:FontStyleRegular andSize:14];

    [wrapperView addSubview:titleLabel];

    /* body wrapper */

    CGPoint bodyWrapperMargin = CGPointMake(10,8);

    CGPoint bodyWrapperViewOrigin = CGPointMake(bodyWrapperMargin.x,CGRectGetMaxY(titleLabel.frame) + bodyWrapperMargin.y);
    CGSize bodyWrapperViewSize = CGSizeMake(headerSize.width - bodyWrapperMargin.x * 2,headerSize.height - bodyWrapperViewOrigin.y - bodyWrapperMargin.y);

    UIView *bodyWrapperView = [UIView viewWithFrame:CGEasyRectMake(bodyWrapperViewOrigin,bodyWrapperViewSize)];

    [wrapperView addSubview:bodyWrapperView];

    /* image */

    NSInteger imageSize = 56;
    NSString *imageName = [self getCategoryResourceItem:section + 1][@"image"];

    UIImageView *imageView = [UIImageView imageViewWithImage:[UIImage imageNamed:imageName] andFrame:CGEasyRectMake(CGPointZero,CGEqualSizeMake(imageSize))];

    imageView.layer.masksToBounds = YES;
    imageView.layer.cornerRadius = imageSize / 2;

    [bodyWrapperView addSubview:imageView];

    /* labels */

    NSInteger labelsWidth = 60;

    UILabel *firstLabel = [UILabel labelWithText:@"first" andFrame:CGRectMake(imageSize + bodyWrapperMargin.x,labelsWidth,16)];

    [bodyWrapperView addSubview:firstLabel];

    UILabel *secondLabel = [UILabel labelWithText:@"second" andFrame:CGRectMake(imageSize + bodyWrapperMargin.x,20,16)];

    [bodyWrapperView addSubview:secondLabel];

    UILabel *thirdLabel = [UILabel labelWithText:@"third" andFrame:CGRectMake(imageSize + bodyWrapperMargin.x,40,16)];

    [bodyWrapperView addSubview:thirdLabel];

    [@[ firstLabel,secondLabel,thirdLabel ] forEachView:^(UIView *view) {
        UILabel *label = (UILabel *)view;

        label.textColor = [UIColor whiteColor];
        label.font = [UIFont fontWithStyle:FontStyleLight andSize:11];
    }];

    /* line */

    UIView *lineView = [UIView viewWithFrame:CGRectMake(imageSize + labelsWidth + bodyWrapperMargin.x * 2,bodyWrapperMargin.y,1,bodyWrapperView.frame.size.height - bodyWrapperMargin.y * 2)];

    lineView.backgroundColor = [UIColor whiteColorWithAlpha:0.2];

    [bodyWrapperView addSubview:lineView];

    /* progress */

    CGPoint progressSliderOrigin = CGPointMake(imageSize + labelsWidth + bodyWrapperMargin.x * 3 + 1,bodyWrapperView.frame.size.height / 2 - 15);
    CGSize progressSliderSize = CGSizeMake(bodyWrapperViewSize.width - bodyWrapperMargin.x - progressSliderOrigin.x,30);

    UISlider *progressSlider = [UISlider viewWithFrame:CGEasyRectMake(progressSliderOrigin,progressSliderSize)];

    progressSlider.value = [self getCategoryProgress];

    [bodyWrapperView addSubview:progressSlider];

    return wrapperView;
}

我希望它看起来像这样:

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

    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    }

    SectionView *sectionView = ... // get the view that is already designed in the Interface Builder

    sectionView.headerText = self.categoriesNames[section];
    sectionView.headerImage = [self getCategoryResourceItem:section + 1][@"image"];

    sectionView.firstLabelText = @"first";
    sectionView.secondLabelText = @"second";
    sectionView.thirdLabelText = @"third";

    sectionView.progress = [self getCategoryProgress];

    return wrapperView;
}

编辑2:我不使用故事板,只是.xib文件.此外,我没有一个UITableViewController,只是一个UIViewController,其中我添加了一个UITableView.

解决方法

故事板或XIB

>相同的故事板:

return tableView.dequeueReusableCell(withIdentifier: "header")


>分离XIB(附加步骤:您必须先注册该Nib):

tableView.register(UINib(nibName: "XIBSectionHeader",bundle:nil),forCellReuseIdentifier: "xibheader")

要从故事板而不是XIB加载,请参阅this Stack Overflow answer.

使用UITableViewCell在IB中创建节标题

利用一个section头是一个普通的UIView,UITableViewCell也是一个UIView的事实.在Interface Builder中,拖动&将表视图单元格从对象库中删除到表视图原型内容.

向新添加的表视图单元添加标识符,并根据需要自定义其外观.对于这个例子,我使用了标题.

使用dequeueReusableCell:withIdentifier来定位您的段标题,就像任何表视图单元格一样.您将需要提供heightForHeaderInSection,为了清楚,硬编码为44

//MARK: UITableViewDelegate
override func tableView(_ tableView: UITableView,viewForHeaderInSection section: Int) -> UIView?
{
    // This is where you would change section header content
    return tableView.dequeueReusableCell(withIdentifier: "header")
}

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

Swift 2&早期:

return tableView.dequeueReusableCellWithIdentifier("header") as? UIView
self.tableView.registerNib(UINib(nibName: "XIBSectionHeader",forCellReuseIdentifier: "xibheader")

►在GitHub上查找此解决方案,并在Swift Recipes上查看更多详细信息.

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...