1

我正在实现一个 UITableView,其中表格单元格包含多个控件,例如标签和按钮。单元格顶部的标签之一可以包含不同数量的文本,因此每个单元格的整体大小也必须有所不同。所以基本上,这是您在各处看到的动态表格单元格问题。

我似乎找到的事实上的解决方案是我正在使用的这个 ,但我不太关心它,因为它带有维护问题。由于单元格中有很多其他东西,我必须有很多硬编码的高度来表示在确定单元格的整体大小和根据单元格的大小布置所有内容时必须考虑的所有其他控件动态内容。

这是一些代码:

- (CGFloat) tableView:(UITableView*)tableView
            heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
    SomeDataItem* item = [self.myData objectAtIndex:indexPath.row];
    CGSize constraintSize = CGSizeMake(275, MAXFLOAT);
    CGSize labelSize = [item.message sizeWithFont:[UIFont systemFontOfSize:13]
                                constrainedToSize:constraintSize 
                                    lineBreakMode:UILineBreakModeWordWrap];

    return HEADER_HEIGHT + OUTER_MARGIN + labelSize.height +
           INNER_MARGIN + INNER_MARGIN + OUTER_MARGIN +
           BUTTON_HEIGHT + OUTER_MARGIN;
}

- (UITableViewCell*)tableView:(UITableView*)tableView
                    cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    ...
    NSString* message = //some dynamic text
    CGSize constraintSize = CGSizeMake(275, MAXFLOAT);
    CGSize labelSize = [message sizeWithFont:[UIFont systemFontOfSize:13]
                           constrainedToSize:constraintSize
                               lineBreakMode:UILineBreakModeWordWrap];

    //resize label according to amount of text
    cell.messageLabel.frame = CGRectMake(cell.messageLabel.frame.origin.x,
                                         cell.messageLabel.frame.origin.y,
                                         cell.messageLabel.frame.size.width, 
                                         labelSize.height);

    //now move controls below the dynamic label down
    y = HEADER_HEIGHT + OUTER_MARGIN;
    [self setView:cell.messageTextBackground yCoord:y];

    y += INNER_MARGIN;
    [self setView:cell.messageLabel yCoord:y];

    y += labelSize.height;
    [self setView:cell.anotherLabel yCoord:y];

    y += OUTER_MARGIN;
    [self setView:cell.someButton yCoord:y];
}

- (void) setView:(UIView*)view yCoord:(NSInteger)y
{
    int x = view.frame.origin.x;
    int w = view.frame.size.width;
    int h = view.frame.size.height;
    view.frame = CGRectMake(x, y, w, h);
}

这只是代码的一种近似,让您了解我在做什么。如您所见,这有点混乱。如果我必须为动态标签旁边的所有其他控件保留#define 值。如果我想更改任何这些控件的大小,我必须在 XIB 文件中进行,然后还要记住更新#define 值。更糟糕的是,如果我想引入一些新的控件,我必须同时修改这两种方法,并确保一切仍然得到正确计算和偏移。

这对我来说似乎很荒谬,但我还没有找到任何其他方法来做到这一点。如果您可以访问 tableView:heightForRowAtIndexPath 中的表格单元格,那么您可以根据实际控件计算所有内容,而不必对所有内容进行硬编码。但是,根据我阅读和体验的内容, tableView:heightForRowAtIndexPath 在单元格存在之前就被调用了,所以你不能这样做。

我不知道我是如何处理这个问题的,还是这是唯一的出路?

4

2 回答 2

3

更干净地处理此问题的一种可能方法是将所有不变的视图/控件放入具有固定大小的父视图中,然后您可以只询问该视图的框架并使用高度。这样,如果您编辑视图的静态部分,则无需更改大小调整代码。由于您只需移动封闭视图,因此还可以更轻松地向下移动静态项目。

于 2012-05-31T21:41:27.047 回答
1

我认为你在做正确的事。至少我是这样做了一段时间的。维护应该没问题,你只需要做你提到的事情。

您也许可以#define通过使用单元格的 XIB 文件、加载 xib 文件viewDidLoad并提取那里的各种元素的大小来减少您的语句。然后,您以后只需在 XIB 文件中更改它们。

当然,包含不变元素的包装视图可能是一个额外的帮助。

于 2012-05-31T21:42:49.123 回答