gpt4 book ai didi

ios - 在 Interface Builder 中设计 UITableView 的部分标题

转载 作者:IT王子 更新时间:2023-10-29 07:52:08 25 4
gpt4 key购买 nike

我有一个带有 UITableViewxib 文件,我想使用委托(delegate)方法 tableView:viewForHeaderInSection: 为其添加自定义节标题 View >。是否有可能在 Interface Builder 中设计它,然后以编程方式更改它的某些 subview 的属性?

我的 UITableView 有更多的部分标题,所以在 Interface Builder 中创建一个 UIView 并返回它是行不通的,因为我有复制它,但没有任何好的方法可以做到这一点。归档和取消归档它对 UIImage 不起作用,因此 UIImageView 会显示为空白。

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

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

我希望它看起来像这样:

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

最佳答案

# Storyboard或 XIB。 2020 年更新。

  1. 相同的 Storyboard:

     return tableView.dequeueReusableCell(withIdentifier: "header")

    Two Section Headers

  2. 分离XIB(附加步骤:您必须先注册那个Nib):

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

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


#在IB中使用UITableViewCell创建Section Header

利用部分标题是常规 UIView 并且 UITableViewCell 也是 UIView 这一事实。在 Interface Builder 中,将 Table View CellObject Library 拖放到您的Table View Prototype Content

(2020)在现代 Xcode 中,只需增加“动态原型(prototype)”数量即可放入更多单元格:

enter image description here

向新添加的 Table View Cell 添加一个Identifier,并自定义其外观以满足您的需要。对于此示例,我使用了 header

Edit the cell

使用 dequeueReusableCell:withIdentifier 定位单元格,就像定位任何表格 View 单元格一样。

不要忘记它只是一个普通单元格:但您要将它用作标题。

对于 2020 年,只需向 ViewDidLoad 添加四行代码:

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 70 // any reasonable value is fine
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedSectionHeaderHeight = 70 // any reasonable value is fine

{例如参见 this进行讨论。

您的标题单元格高度现在是完全动态的。可以更改标题中文本的长度等。

(提示:纯粹关于 Storyboard :只需选择...

enter image description here

...在 Storyboard 中,以便 Storyboard 正常工作。这对最终构建绝对没有影响。选择该复选框对最终构建绝对没有任何影响。如果高度是动态的,它的存在纯粹是为了让 Storyboard正常工作。)


在较旧的 Xcode 中,或者,如果出于某种原因您不想使用动态高度:

只需提供 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", bundle:nil),
forCellReuseIdentifier: "xibheader")

► 在 GitHub 上找到此解决方案以及有关 Swift Recipes 的更多详细信息.

关于ios - 在 Interface Builder 中设计 UITableView 的部分标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31693901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com