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

时间:2010-10-20 05:11:36

标签: iphone uiview uitableview subclass

我目前有一个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具有正确的高度)之外,所有子视图的大小都正确。我不应该从这种方法调整视图的大小吗?有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

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

像这样使用:

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

答案 1 :(得分:1)

如果我更换

[tableHeaderView setNeedsLayout];

[tableHeaderView layoutSubviews];

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

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