UITableView 滚动时奇怪的布局行为变化

Posted

技术标签:

【中文标题】UITableView 滚动时奇怪的布局行为变化【英文标题】:UITableView strange layout behavior changes on scroll 【发布时间】:2015-03-24 11:26:04 【问题描述】:

我有一个 UITableView 和自定义 UITableViewCell 设计为具有自动高度。

行为是在我的UIViewControllerUITableView 的第一次加载中显示我的标签和部分文本。然后当我滚动到底部然后滚动到顶部时,我会得到所需的高度和文本外观。

截图如下:

初始查找视图控制器:

这是滚动底部然后顶部后的外观(这是我的实现的正确外观,一些 Lorem 文本已被我删除):

编辑 1:

代码:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 101 // much heigher than most cells. But no use.

在 UI Builder 中,UITableViewCell 的“行高”设置为“默认”(未选中自定义)

在 UI Builder 中,UITableView 的“行高”设置为“101”(也尝试将其设置为“0”但结果相同。)

【问题讨论】:

【参考方案1】:

在 UITableViewCell 上使用自动布局是为了确保您有约束将每个子视图固定在所有边上——也就是说,每个子视图应该有前导、顶部、尾随和底部约束。

此外,您需要从 contentView 的顶部到底部有一条清晰的约束线。这样可以确保自动布局根据其子视图正确确定 contentView 的高度。

棘手的部分是,如果您缺少其中一些约束,Interface Builder 通常不会警告您;运行项目时,自动布局根本不会返回正确的高度。例如,它可能为单元格高度返回 0,这是您的约束需要更多工作的线索。

如果您在处理自己的项目时遇到问题,请尝试调整您的约束条件,直到满足上述条件。

查看链接了解详情:http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift

【讨论】:

提供的教程(我已经知道)已经解决了它,我重新创建了一个新的原型单元并按照教程添加了一个UIImageView 一切都很好。我试图通过检查自定义单元格的所有属性和教程中的自定义单元格来找出我的错误。我找不到问题所在。谢谢。【参考方案2】:

我觉得你可以使用heightForRowAtIndexPath方法

 override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat 

    var heightToReturn : CGFloat = 0

    heightToReturn = StringUtil.findHeightForText("your text", havingWidth: "your label width" , andFont: UIFont.systemFontOfSize("font size"))  + // add some buffer for padding

    if heightToReturn < 101
    
        heightToReturn = 101
    
    return heightToReturn
    


并使用此方法计算文本的高度

+ (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font 
CGFloat result = font.pointSize+4;
if (text) 
    CGSize size;

    CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX)
                                      options:NSStringDrawingUsesLineFragmentOrigin
                                   attributes:@NSFontAttributeName:font
                                      context:nil];
    size = CGSizeMake(frame.size.width, frame.size.height+1);
    result = MAX(size.height, result); //At least one row


return result;

【讨论】:

如何在heightForRowAtIndexPath 处获取标签的宽度,这显然是在创建我的单元格的cellForRowAtIndexPath 之前调用的? 我按照其他用户的回答解决了这个问题,但是我一直害怕触摸heightForRowAtIndexPath 我认为它很高级,但结果却是基础。谢谢你。

以上是关于UITableView 滚动时奇怪的布局行为变化的主要内容,如果未能解决你的问题,请参考以下文章

滚动 UITableView 的奇怪行为

UITableView 使用超过 1 个原型单元时的奇怪行为

水平滚动 UITableView 的奇怪行为(在 Monotouch 中)

UITableView 奇怪的行为

UITableView 方法“indexPathForRowAtPoint:”的奇怪行为

UITableView 在旋转时使用自动布局调整大小