在Interface Builder中设计UITableView的节头 [英] Design UITableView's section header in Interface Builder

查看:63
本文介绍了在Interface Builder中设计UITableView的节头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a xib file with a UITableView for which I want to add a custom section header view using the delegate method tableView:viewForHeaderInSection:. Is there any possibility to design it in Interface Builder and then change some of it's subview's properties programmatically?

我的 UITableView 有更多节标题,因此在界面生成器中创建一个 UIView 并且返回它不起作用,因为我必须复制它,但没有任何好的方法来做它。归档和取消归档它不适用于 UIImage s所以 UIImageView s将显示为空白。

My UITableView has more section headers so creating one UIView in Interface Builder and returning it doesn't work, because I'd have to duplicate it, but there isn't any good method of doing it. Archiving and unarchiving it doesn't work for UIImages so UIImageViews would show up blank.

另外,我不想以编程方式创建它们,因为它们太复杂,结果代码很难读取和维护。

Also, I don't want to create them programmatically because they are too complex and the resulting code would be hard to read and maintain.

编辑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, 0, labelsWidth, 16)];

    [bodyWrapperView addSubview:firstLabel];

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

    [bodyWrapperView addSubview:secondLabel];

    UILabel *thirdLabel = [UILabel labelWithText:@"third" andFrame:CGRectMake(imageSize + bodyWrapperMargin.x, 40, labelsWidth, 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;
}

我希望它看起来像这样:

and I would want it to look something like this:

- (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 :我没有使用 Storyboard ,只需 .xib 文件。另外,我没有 UITableViewController ,只是一个 UIViewController ,其中我添加了 UITableView

Edit 2: I'm not using a Storyboard, just .xib files. Also, I don't have an UITableViewController, just an UIViewController in which I added an UITableView.

推荐答案

我终于使用 this教程,主要由以下(适用于我的示例)组成:

I finally solved it using this tutorial, which, largely consists of the following (adapted to my example):


  1. 创建 SectionHeaderView 类的子类 UIView

  2. 创建 SectionHeaderView.xib 文件并将其文件所有者 CustomClass 设置为 SectionHeaderView class。

  3. 中创建 UIView 属性。 m 文件如: @property(强,非原子)IBOutlet UIView * viewContent;

  4. 连接的.xib 查看到此 viewContent outlet。

  5. 添加如下所示的初始化方法:

  1. Create SectionHeaderView class that subclasses UIView.
  2. Create SectionHeaderView.xib file and set it's File's Owner's CustomClass to the SectionHeaderView class.
  3. Create an UIView property in the .m file like: @property (strong, nonatomic) IBOutlet UIView *viewContent;
  4. Connect the .xib's View to this viewContent outlet.
  5. Add an initializer method that looks like this:

+ (instancetype)header {

    SectionHeaderView *sectionHeaderView = [[SectionHeaderView alloc] init];

    if (sectionHeaderView) { // important part
        sectionHeaderView.viewContent = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:sectionHeaderView options:nil] firstObject];

        [sectionHeaderView addSubview:sectionHeaderView.viewContent];

        return sectionHeaderView;
    }

    return nil;
}


然后,我添加了 .xib 文件中的 UILabel 并将其连接到 labelCategoryName outlet并在 SectionHeaderView 类中实现 setCategoryName:方法,如下所示:

Then, I added an UILabel inside the .xib file and connected it to the labelCategoryName outlet and implemented the setCategoryName: method inside the SectionHeaderView class like this:

- (void)setCategoryName:(NSString *)categoryName {

    self.labelCategoryName.text = categoryName;
}

然后我实现了 tableView:viewForHeaderInSection:这样的方法:

I then implemented the tableView:viewForHeaderInSection: method like this:

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

    SectionHeaderView *sectionHeaderView = [SectionHeaderView header];

    [sectionHeaderView setCategoryName:self.categoriesNames[section]];

    return sectionHeaderView;
}

它最终奏效了。每个部分都有自己的名字,并且 UIImageView 正确显示。

And it finally worked. Every section has it's own name, and also UIImageViews show up properly.

希望它可以帮助其他人绊倒在整个网络上,一遍又一遍地使用相同的错误解决方案,就像我一样。

Hope it helps others that stumble over the same wrong solutions over and over again, all over the web, like I did.

这篇关于在Interface Builder中设计UITableView的节头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆