这个问题在SO上被问了100次,但我无法解决我的问题。
我有两个可自定义的单元格。两者都有动态高度。我的tableView:heightForRowAtIndexPath:
返回每个单元格的正确高度,但是当重复使用单元格时,单元格之间的分隔线在100%的时间内不在正确的位置。我无法使用在我的单元格中添加自己的行的黑客攻击,因为有时重叠非常糟糕,您无法单击右侧单元格。
我需要做些什么来确保它使用正确的高度?
以下是分隔线位于错误位置(假设位于标题正上方)的示例:
screenshot http://f.cl.ly/items/2z1e3s0N1g213R414129/Screenshot_2013.11.27_17.49.45.png
以下是我设定的高度:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
InspectionItem *item = [items objectAtIndex:indexPath.row];
int t = [item.rating.ratingType ratingTypeK];
if (t == RatingTypeTextfield){
CGFloat height = [OQCTextFieldCell heightOfCellWithTitle:item.name
subtext:item.descriptionText
text:item.comment
andScreenWidth:self.view.frame.size.width];
return height;
}
else {
CGFloat height = [OQCButtonCell heightOfCellWithTitle:item.name
subtext:item.descriptionText
andScreenWidth:self.view.frame.size.width];
return height;
}
}
同样,这些类方法返回正确的高度。
以下是我设置单元格的方法(简短版本):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
InspectionItem *item = [items objectAtIndex:indexPath.row];
int t = [item.rating.ratingType ratingTypeK];
if (t == RatingTypeTextfield){
static NSString *CellIdentifier = @"TextFieldCell";
OQCTextFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.titleLabel.text = item.name;
...
return cell;
}
else {
static NSString *CellIdentifier = @"ButtonCell";
OQCButtonCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.titleLabel.text = item.name;
...
return cell;
}
}
以下是我如何注册我的单元格:
UINib *buttonNib = [UINib nibWithNibName:@"OQCButtonCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:buttonNib forCellReuseIdentifier:@"ButtonCell"];
UINib *textFieldNib = [UINib nibWithNibName:@"OQCTextFieldCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:textFieldNib forCellReuseIdentifier:@"TextFieldCell"];
UINib *flagNib = [UINib nibWithNibName:@"OQCFlagCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:flagNib forCellReuseIdentifier:@"FlagCell"];
我的细胞只覆盖layoutSubviews
,他们确实称之为超级优先。
我需要解决方案才能适用于iOS 5.2 +。
更新
以下是layoutSubviews
的代码。我相信我的自定义方法heightOfCellWithTitle:subtext:text:
会返回正确的高度,因为它与此方法末尾的layoutSubview
height
变量相匹配。
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat height = 0;
// Title + Header background view
NSString *title = titleLabel.text;
CGRect frame = self.titleLabel.frame;
CGSize size = [title sizeWithFont:titleLabel.font
constrainedToSize:CGSizeMake(frame.size.width, 9999)
lineBreakMode:titleLabel.lineBreakMode];
size.width = frame.size.width; // don't let it shrink
titleLabel.numberOfLines = size.height / titleLabel.font.lineHeight;
frame.size = size;
self.titleLabel.frame = frame;
frame = self.headerBackgroundView.frame;
frame.size.height = size.height + 8;
self.headerBackgroundView.frame = frame;
// single line of text should be 30
height += frame.size.height;
CGRect subContentFrame = subContentView.frame;
subContentFrame.origin.y = height;
CGFloat subHeight = 0;
// Label
title = subtextLabel.text;
if ([title length] > 0){
subHeight += 5; // top margin
size = [title sizeWithFont:subtextLabel.font
constrainedToSize:CGSizeMake(subtextLabel.frame.size.width, 9999) lineBreakMode:subtextLabel.lineBreakMode];
size.width = self.contentView.frame.size.width - 52; // don't let it shrink
subtextLabel.numberOfLines = size.height / subtextLabel.font.lineHeight;
frame = self.subtextLabel.frame;
frame.size = size;
frame.origin.y = subHeight;
self.subtextLabel.frame = frame;
// subtext height + bottom margin
subHeight += size.height + 5;
}
else {
subHeight += 25;
}
// Button
frame = button.frame;
frame.origin.y = subHeight;
button.frame = frame;
subHeight += frame.size.height + 25;
subContentFrame.size.height = subHeight;
subContentView.frame = subContentFrame;
// reposition detailIndicator
frame = self.detailIndicator.frame;
frame.origin.x = subContentView.frame.size.width - 37;
self.detailIndicator.frame = frame;
height += subHeight;
// Drawer
frame = CGRectMake(0, 0, self.frame.size.width, height);
[self.drawerView setFrame:frame];
self.backgroundView = self.drawerView;
}
另外,快速记下我一直在检查的数字。
我有一个layoutSubviews
和tableView:heightForRowAtIndexPath:
登录,它给了我正确的高度(我基于layoutSubviews
,因为它重新计算整个单元格的高度)。然后我有tableView:cellForRowAtIndexPath:
的日志,在我返回单元格的最后,我打印出单元格的高度,这是一个重用视图的旧高度,我有点期待。我将假设在返回单元格后,iOS将根据tableView:heightForRowAtIndexPath:
重新计算单元格的位置,并使用layoutSubviews
重新定位视图。
答案 0 :(得分:0)
所以如果你在单元格类中动态布局单元格并覆盖layoutSubviews,这在heightForRowAtIndexPath中应该足够了:
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
float height = cell.frame.size.height;
return height;
请记住,您必须将单元格中的所有uiviews“重置”为起始值。否则,单元格将使用当前值,即如果您在y = 10处有标签并将其以编程方式设置为y = 20,则下次使用该单元格时,单元格仍具有y = 20。
答案 1 :(得分:0)
您是否尝试过调用
[cell setNeedsLayout];
[cell layoutIfNeeded];
返回之前?