Ios 动态高度可重用UITableViewCell

Ios 动态高度可重用UITableViewCell,ios,objective-c,uitableview,Ios,Objective C,Uitableview,这个问题已经被问了100次了,但我无法解决我的问题 我有两个可定制的单元格。两者都可以具有动态高度。MytableView:heightForRowAtIndexPath:返回每个单元格的正确高度,但是当重复使用单元格时,单元格之间的分隔线在100%的时间内都不在正确的位置。我不能使用在我的单元格中添加我自己的行的方法,因为有时重叠非常严重,以至于你无法单击正确的单元格 我需要做什么来确保它使用正确的高度 下面是分隔线位于错误位置的示例(假设位于标题正上方): 以下是我如何设定我的高度: -

这个问题已经被问了100次了,但我无法解决我的问题

我有两个可定制的单元格。两者都可以具有动态高度。My
tableView:heightForRowAtIndexPath:
返回每个单元格的正确高度,但是当重复使用单元格时,单元格之间的分隔线在100%的时间内都不在正确的位置。我不能使用在我的单元格中添加我自己的行的方法,因为有时重叠非常严重,以至于你无法单击正确的单元格

我需要做什么来确保它使用正确的高度

下面是分隔线位于错误位置的示例(假设位于标题正上方):

以下是我如何设定我的高度:

- (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;
    }
}
同样,这些类方法返回正确的高度

以下是我如何设置我的单元格(简短版本):

以下是我注册手机的方式:

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
,它们会首先调用super

我需要适合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:cellforrowatinexpath:
的日志,在我返回单元格之前的最后,我打印出了单元格的高度,这是一个重用视图的旧高度,我有点期待。我假设在返回单元格后,iOS将根据
tableView:heightForRowAtIndexPath:
重新计算单元格的位置,并使用
布局子视图重新定位视图,因此如果您在单元格类中动态布局单元格并覆盖布局子视图,这应该足够了ROWATINDEXPATH的高度:

UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
float height = cell.frame.size.height;
return height;
请记住,必须将单元格中的所有UIView“重置”为起始值。否则,单元格将使用当前值,即如果您在y=10处有一个标签,并以编程方式将其设置为y=20,则下次使用单元格时,该单元格仍具有y=20

你打过电话吗

[cell setNeedsLayout];
[cell layoutIfNeeded];

在返回它之前?

heightOfCellWithTitle返回正确的高度?假设(t==RatingTypeTextfield)的计算结果符合您的要求,并且heightOfCell方法返回正确的高度,我看不到代码中有任何错误或缺失。您在布局子视图中做什么?这似乎是一个可能导致这个问题的地方。@astri-我已经更新了这个问题,但是是的,我相信它的高度是正确的@rdelmar-我已经在我的问题中添加了
layoutSubviews
代码。正如我在下面所写的,我认为问题在于每次重复使用单元格时,框架等的开始值都不同。请尝试将layoutSubviews开始处的subcentview、self.drawerView和self.backgroundView设置为默认值,因此,每次调用LayoutSubView时,所有的值都是相同的。经过太多的计算,您是否尝试使用autolayout功能构建单元布局,并返回heightForRowAtIndexPath automatic height?您打算在哪里重置UIView?我将发布布局子视图的代码,这可能有助于回答此问题。我尝试了您对RowAtIndexPath:
的高度的建议,但当您滚动时,它会使所有内容都跳转,并且计算似乎完全关闭。我在不同uiviewcontroller和带有dynamic的tableviewcontroller中的不同TableView中使用此选项单元高度,单元视图在单元中完全设置,且工作正常。也许这表明你的代码设置不正确是的,我想得越多,我就同意你的看法。我希望我能很容易地创建一个它看起来像什么的gif。当它穿过一条分隔线时,重叠单元格(顶部单元格)消失,它下面的单元格就在分隔线的正下方。所以我试图找出我的代码的哪一部分是错误的。在layoutSubviews中,如何正确设置单元格本身的框架?我从来没有接触过单元格的边框,我只是调整子视图。但对于这两种情况,它仍然无法计算行分隔符。谢谢你的建议。
[cell setNeedsLayout];
[cell layoutIfNeeded];