2010-10-20 146 views
3

我目前有一个UIView子类,充当我的UITableViewController的标题视图。所有子视图的大小取决于为特定项目检索的数据。使用动态大小的子视图调整UIView子类的大小

在我可以确定每个标签的大小之前,layoutSubViews正在调用UIView。这会导致问题,因为我在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具有正确的高度)。我不应该从这个方法调整视图的大小吗?有没有更好的方法呢?

回答

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

我试过你的建议,在设置标签的内容后调用[tableHeaderView sizeToFit],但我认为我真正的问题在于,一旦setTableHeaderView:tableHeaderView被调用,表头的大小不会改变。 [tableHeaderView setNeedsLayout]不会调用layoutSubViews方法,直到将视图设置为标题之后。因此,无论我以什么样的大小设置视图,它都不会影响标题的大小。 – avenged 2010-10-20 19:04:44

+1

我没有说要调用它,你需要**在你的子类上实现** sizeThatFits并返回你想要的大小。 – 2010-10-20 19:39:19

+0

对不起,我首先想说的是我确实实现了sizeThatFits来返回标题视图的正确大小。问题是,一旦sizeToFit被调用(我想你想让我在设置标签后调用它),tableHeaderView已经被设置为表视图标题。 – avenged 2010-10-20 19:45:12

1

如果我更换

[tableHeaderView setNeedsLayout]; 

[tableHeaderView layoutSubviews]; 

头的看法是正确的大小。发生这种情况是因为在视图设置为标题视图之前,setNeedsLayout不会调用layoutSubViews。如果我直接调用layoutSubViews,那么在设置视图之前会调用layoutSubviews。

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

+0

在setNeedsLayout之后调用layoutIfNeeded。 – hybridcattt 2014-06-16 12:45:28

相关问题