首次加载 UITableViewController 时自定义 UITableViewCell 无法正确显示
Posted
技术标签:
【中文标题】首次加载 UITableViewController 时自定义 UITableViewCell 无法正确显示【英文标题】:Custom UITableViewCell not displaying correctly when UITableViewController first loads 【发布时间】:2012-02-10 11:14:30 【问题描述】:我使用以下代码创建了一个自定义 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
在调用 layoutSubviews 之前,它运行了 8 次(每个单元格首先为表格视图显示一个)。在此之后调用 layoutSubviews (因此格式不正确)。我应该在这里添加一个 [cell layoutSubviews](它确实有效,但之后会再次调用它)还是有其他方法?
【问题讨论】:
那么,你在willDisplayCell
中做了什么导致这种情况?我建议在cellForRowAtIndexPath
中尽可能多地设置单元格,或者您在willDisplayCell
中调用单元格的任何方法都应该调用setNeedLayout
,如果更改该数据意味着它需要布局。
【参考方案1】:
我解决了(我对这个错误有点尴尬)但我最初设置的 CGRect 尺寸不正确。我将高度作为宽度,将宽度作为高度。代码应该是:
CGRect frame = CGRectMake(0, 0, mapButtonWidth, h);
一个很容易犯的错误,但会产生不寻常的结果。
【讨论】:
以上是关于首次加载 UITableViewController 时自定义 UITableViewCell 无法正确显示的主要内容,如果未能解决你的问题,请参考以下文章