UITableViewController首次加载时,自定义UITableViewCell无法正确显示

时间:2012-02-10 11:14:31

标签: objective-c cocoa-touch uitableview

我使用以下代码创建了自定义UITableViewCell:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {

        mapButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];       
        [[self contentView] addSubview:mapButton];        

        houseNumberLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        [[self contentView] addSubview:houseNumberLabel];
        [houseNumberLabel release];

        NSArray *segmentArray = [[NSArray alloc] initWithObjects:@"Yes", @"No", nil];
        segmentedControl = [[UISegmentedControl alloc] initWithItems:segmentArray];
        [segmentArray release];
        [segmentedControl setSegmentedControlStyle:UISegmentedControlStyleBar];
        [[self contentView] addSubview:segmentedControl];
        [segmentedControl release];

        disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
        [[self contentView] addSubview:disclosureButton];              
    }

    return self;
}

然后我使用以下代码覆盖了自定义单元格中的layoutSubviews方法:

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGRect viewBounds = [[self contentView] bounds];
    float h = viewBounds.size.height;
    float w = viewBounds.size.width;

    float inset = 20.0;
    float mapButtonWidth = mapButton.frame.size.width;
    float segmentWidth = 140.0;
    float disclosureButtonWidth = disclosureButton.frame.size.width;
    float houseNumberLabelWidth = viewBounds.size.width - (mapButtonWidth + inset + inset + segmentWidth + inset + disclosureButtonWidth + inset);

    CGRect frame = CGRectMake(0, 0, h, mapButtonWidth);
    [mapButton setFrame:frame];

    frame.origin.x += mapButtonWidth + inset;
    frame.size.width = houseNumberLabelWidth;
    [houseNumberLabel setFrame:frame];

    frame.origin.x += houseNumberLabelWidth + inset;
    frame.size.width = segmentWidth;
    [segmentedControl setFrame:frame];

    frame.origin.x += segmentWidth + inset;
    frame.size.width = disclosureButtonWidth;
    [disclosureButton setFrame:frame];
}

我已将日志添加到这些函数中,并且每次创建单元格时都会调用它们。问题是当UITableViewController首次加载并显示单元格正在显示格式化的单元格时,就像从未调用layoutSubviews一样(即使根据它具有的日志)。但是,当我滚动表格视图时,新单元格(屏幕外)会正确显示。然后我向后滚动,第一个单元格现在正确。就像调用layoutSubviews一样,但是当第一次加载表视图时,它无法实现它需要使用新布局进行渲染。

我已经向viewWillAppear添加了一个reloadData,它部分修复了问题,但是最后一个单元格(就在屏幕外)仍然呈现不正确的方式。我把头发拉了出来。

[SUBNOTE]我刚刚添加了一个日志:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

这是运行8次(每个单元格首先显示一个用于表视图)在调用layoutSubviews之前。之后调用layoutSubviews(因此格式不正确)。我应该在这里添加一个[cell layoutSubviews](它确实可以工作但之后会再次调用)还是有另一种方式?

1 个答案:

答案 0 :(得分:0)

我解决了(我对这个错误感到有些尴尬)但我最初设置的CGRect尺寸不正确。我正在为高度增加宽度和宽度。代码应该是:

CGRect frame = CGRectMake(0, 0, mapButtonWidth, h);

一个容易出错的错误,但会产生不寻常的结果。