在 Interface Builder 中设计 UITableView 的部分标题 [英] Design UITableView's section header in Interface Builder

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

问题描述

我有一个带有 UITableViewxib 文件,我想使用委托方法为该文件添加自定义部分标题视图 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 有更多的部分标题,所以在 Interface Builder 中创建一个 UIView 并返回它不起作用,因为我有复制它,但没有任何好的方法来做到这一点.存档和取消存档对 UIImages 不起作用,因此 UIImageViews 会显示为空白.

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

Edit 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.

推荐答案

我终于用本教程,主要包括以下内容(适应我的例子):

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

  1. 创建子类 UIViewSectionHeaderView 类.
  2. 创建SectionHeaderView.xib 文件并将其File's OwnerCustomClass 设置为SectionHeaderView 类.
  3. .m 文件中创建一个 UIView 属性,例如:@property (strong, nonatomic) IBOutlet UIView *viewContent;
  4. .xibView 连接到这个 viewContent 出口.
  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 插座并实现了 setCategoryName:SectionHeaderView 类中的 方法如下:

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天全站免登陆