使用动态大小的子视图调整 UIView 子类的大小

发布于 2024-09-28 05:25:23 字数 1954 浏览 1 评论 0原文

我目前有一个 UIView 子类,充当 UITableViewController 的标题视图。所有子视图的大小都不同,具体取决于为特定项目检索的数据。

在我确定每个标签的大小之前,UIView 会调用layoutSubViews。这会导致问题,因为我在layoutSubViews方法中设置了视图的大小。由于它在我设置标签之前被调用,因此视图高度始终为 0。即使在设置标签之后我调用 setNeedsLayout 但表视图标题大小也不会改变。

这将创建我的 TableHeaderView 并设置标签的文本。

    TableHeaderView *tableHeaderView = [[TableHeaderView alloc] initWithFrame:CGRectZero];
    tableHeaderView.headerTitle.text = title;
    tableHeaderView.headerOption1.text = headerOption1
    tableHeaderView.headerOption2.text = headerOption2
    tableHeaderView.headerOption3.text = headerOption3

    [[self tableView] setTableHeaderView:tableHeaderView];

    [tableHeaderView setNeedsLayout];
    [tableHeaderView release];

这是我的 UIView 子类

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {

     UIView *headerView = self;

     self.headerTitle = [[UILabel alloc] initWithFrame:CGRectZero];
     self.headerTitle.numberOfLines = 3;
     self.headerTitle.lineBreakMode = UILineBreakModeWordWrap;
     [headerView addSubview:self.headerTitle];
     [self.headerTitle release];

     self.headerOption1 = [[UILabel alloc] initWithFrame:CGRectZero];
     self.headerOption1.numberOfLines = 2;
     self.headerOption1.lineBreakMode = UILineBreakModeWordWrap;
     [headerView addSubview:self.headerOption1];
     [self.headerOption1 release];
 }
 return self;
}

- (void)layoutSubviews {

 [super layoutSubviews];

 CGSize maxLabelSize;

 /*...*/

 [self.headerTitle setFrame:CGRectMake(10.0f, 10.0f, titleWidth, titleHeight)];

 /*...*/

 [self.headerOption1 setFrame:CGRectMake(10.0f, (self.headerTitle.frame.origin.y + self.headerTitle.bounds.size.height + 2.5f), pubWidth, pubHeight)];

    /*...*/
    [self setFrame:CGRectMake(0.0f, 0.0f, 320.0f, tableHeaderHeight)];
}

第二次调用layoutSubViews时,除了视图本身之外,所有子视图的大小都正确(tableHeaderHeight具有正确的高度)。我不应该通过这种方法调整视图大小吗?有更好的方法吗?

I currently have a UIView subclass that acts as my header view for my UITableViewController. All of the subviews vary in size depending on data retrieved for a particular item.

layoutSubViews is getting called for the UIView before I can determine the size of each label. This causes a problem because I set the size of the view within the layoutSubViews method. Since it gets called before I setup my labels, the views height is always 0. Even after setting up the labels I call setNeedsLayout but the table views header size does not change.

This will create my TableHeaderView and set the text for my labels.

    TableHeaderView *tableHeaderView = [[TableHeaderView alloc] initWithFrame:CGRectZero];
    tableHeaderView.headerTitle.text = title;
    tableHeaderView.headerOption1.text = headerOption1
    tableHeaderView.headerOption2.text = headerOption2
    tableHeaderView.headerOption3.text = headerOption3

    [[self tableView] setTableHeaderView:tableHeaderView];

    [tableHeaderView setNeedsLayout];
    [tableHeaderView release];

Here is my UIView subclass

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {

     UIView *headerView = self;

     self.headerTitle = [[UILabel alloc] initWithFrame:CGRectZero];
     self.headerTitle.numberOfLines = 3;
     self.headerTitle.lineBreakMode = UILineBreakModeWordWrap;
     [headerView addSubview:self.headerTitle];
     [self.headerTitle release];

     self.headerOption1 = [[UILabel alloc] initWithFrame:CGRectZero];
     self.headerOption1.numberOfLines = 2;
     self.headerOption1.lineBreakMode = UILineBreakModeWordWrap;
     [headerView addSubview:self.headerOption1];
     [self.headerOption1 release];
 }
 return self;
}

- (void)layoutSubviews {

 [super layoutSubviews];

 CGSize maxLabelSize;

 /*...*/

 [self.headerTitle setFrame:CGRectMake(10.0f, 10.0f, titleWidth, titleHeight)];

 /*...*/

 [self.headerOption1 setFrame:CGRectMake(10.0f, (self.headerTitle.frame.origin.y + self.headerTitle.bounds.size.height + 2.5f), pubWidth, pubHeight)];

    /*...*/
    [self setFrame:CGRectMake(0.0f, 0.0f, 320.0f, tableHeaderHeight)];
}

The second time that layoutSubViews is called all of the subviews get sized correctly except for the view itself (tableHeaderHeight has the correct height). Should I not be resizing the view from this method? Is there a better approach to this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷︶言冷语的世界 2024-10-05 05:25:23

您可能需要覆盖 sizeThatFits: 在您的 UIView 子类上,根据您的布局返回适当的尺寸。

像这样使用它:

TableHeaderView *tableHeaderView = [[TableHeaderView alloc] initWithFrame:CGRectZero];
tableHeaderView.headerTitle.text = title;
tableHeaderView.headerOption1.text = headerOption1
tableHeaderView.headerOption2.text = headerOption2
tableHeaderView.headerOption3.text = headerOption3

tableHeaderView.frame = (CGRect){
    .origin = tableHeaderView.frame.origin,
    .size = [tableHeaderView sizeThatFits:CGSizeZero],
};

[[self tableView] setTableHeaderView:tableHeaderView];

[tableHeaderView setNeedsLayout]; // I don't think you need this anymore.
[tableHeaderView release];

You likely need to override sizeThatFits: on your UIView subclass to return the appropriate size based on your layout.

Use it like this:

TableHeaderView *tableHeaderView = [[TableHeaderView alloc] initWithFrame:CGRectZero];
tableHeaderView.headerTitle.text = title;
tableHeaderView.headerOption1.text = headerOption1
tableHeaderView.headerOption2.text = headerOption2
tableHeaderView.headerOption3.text = headerOption3

tableHeaderView.frame = (CGRect){
    .origin = tableHeaderView.frame.origin,
    .size = [tableHeaderView sizeThatFits:CGSizeZero],
};

[[self tableView] setTableHeaderView:tableHeaderView];

[tableHeaderView setNeedsLayout]; // I don't think you need this anymore.
[tableHeaderView release];
时光是把杀猪刀 2024-10-05 05:25:23

如果我替换

[tableHeaderView setNeedsLayout];

[tableHeaderView layoutSubviews];

标题视图,则其大小正确。发生这种情况是因为 setNeedsLayout 在视图设置为标题视图之前不会调用layoutSubViews。但是,如果我直接调用layoutSubViews,则将在设置视图之前调用layoutSubviews。

但我过去听说直接调用layoutSubviews不是一个好主意,对于这种情况也是如此吗?

If I replace

[tableHeaderView setNeedsLayout];

with

[tableHeaderView layoutSubviews];

the header view is sized correctly. This is happening because setNeedsLayout does not call layoutSubViews until after the view has been set to the header view. If i directly call layoutSubViews however, layoutSubviews will be called before setting the view.

But I have heard in the past that directly calling layoutSubviews is not a good idea, is that also true for this case?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文