`
lizhuang
  • 浏览: 888231 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

ios7可变高度UITableViewCell

阅读更多
1.In your UITableViewCell subclass, add constraints so that the subviews of the content view have their edges pinned to the edges of the content view (most importantly to the top AND bottom edges). Let the intrinsic content size of these subviews drive the height of the table view cell's content view by making sure the content compression resistance and content hugging constraints in the vertical dimension for each subview are not being overridden by higher-priority constraints you have added.
Remember the idea is to have the subviews connected vertically to the cell's content view so that they can "exert pressure" and make the content view expand to fit them.
If you're adding constraints in code, you should do this once after init in the updateConstraints method.
2.For every unique set of constraints in the cell, use a unique cell reuse identifier. In other words, if your cells have more than one unique layout, each unique layout should receive its own reuse identifier.
For example, if you were displaying an email message in each cell, you might have 4 unique layouts: messages with just a subject, messages with a subject and a body, messages with a subject and a photo attachment, and messages with a subject, body, and photo attachment. Each layout has completely different constraints required to achieve it, so once the cell is initialized and the constraints are added for one of these layouts, the cell should get a unique reuse identifier specific to that layout. This means when you dequeue a cell for reuse, the constraints have already been added and are ready to go for that layout.
Note that due to differences in intrinsic content size, cells with the same constraints (layout) may still have varying heights! Don't confuse fundamentally different layouts (different constraints) with different calculated view frames (solved from identical constraints) due to different sizes of content.
Do not add cells with completely different sets of constraints to the same reuse pool (i.e. use the same reuse identifier) and then attempt to remove the old constraints and set up new constraints from scratch after each dequeue. The internal Auto Layout engine is not designed to handle large scale changes in constraints, and you will see massive performance issues.

After configuring the cell with the content it will hold, force the cell to immediately layout its subviews, and then use the systemLayoutFittingSize: method on the UITableViewCell's contentView to find out what the required height of the cell is. Use UILayoutFittingCompressedSize to get the smallest size required to fit all the contents of the cell. The height can then be returned by the tableView:heightForRowAtIndexPath: delegate method.
If your table view has more than a couple dozen rows in it, you will find that doing the Auto Layout constraint solving can quickly bog down the main thread when first loading the table view, as tableView:heightForRowAtIndexPath: is called on each and every row upon first load (in order to calculate the size of the scroll indicator).
As of iOS 7, you can and absolutely should use the estimatedRowHeight property on the table view, or implement the delegate method tableView:estimatedHeightForRowAtIndexPath:. What this does is allow you to return a guess for the cell height using minimal or no computation, which is used to get a temporary estimate/placeholder for the row height of cells that are not onscreen. Then, when these cells are about to scroll onscreen, the real row height will be calculated and the estimated height updated with the actual one.
Generally speaking, the estimate you provide doesn't have to be very accurate - it's only used to correctly size the scroll indicator in the table view, and the table view does a good job of adjusting it when you scroll and it finds that your estimates were wrong. I would just suggest adding enough logic to make sure your estimated heights are within an order of magnitude of the actual heights.
If you've done all the above and are still finding that performance is unacceptably slow (when doing the constraint solving for the row height calculations), you'll unfortunately need to implement some caching for cell heights. The general idea is to let the Auto Layout engine solve the constraints the first time, then cache the calculated height for that cell and use the cached value for all future requests for that cell's height. The trick of course is to make sure you clear the cached height for a cell when anything happens that could cause the cell's height to change -- primarily, this would be when that cell's content changes or when other important events occur (like the user adjusting the Dynamic Type text size slider).
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Dequeue a cell for the particular layout required (you will likely need to substitute
    // the reuse identifier dynamically at runtime, instead of a static string as below).
    // Note that this method will init and return a new cell if there isn't one available in the reuse pool,
    // so either way after this line of code you will have a cell with the correct constraints ready to go.
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UniqueCellIdentifierForThisUniqueCellLayout"];

    // Configure the cell with content for the given indexPath, for example:
    // cell.textLabel.text = someTextForThisCell;
    // ...

    [cell.contentView setNeedsLayout];
    [cell.contentView layoutIfNeeded];
    CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    return height;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return a fixed constant if possible, or do some minimal calculations if needed to be able to return an
    // estimated row height that's at least within an order of magnitude of the actual height.
    // For example:
    if ([self isLargeTypeForCellAtIndexPath:indexPath]) {
        return 150.0f;
    } else {
        return 60.0f;
    }
}

分享到:
评论

相关推荐

    SwipyCell:易于使用的UITableViewCell,实现滑动以触发动作

    可滑动的UITableViewCell受流行的启发,该在实现。 预习 退出模式 .exit模式是邮箱应用程序中已知的原始行为。 切换模式 .toggle是另一种行为,其中单元格在滑动后会反弹。 安装 Swift软件包管理器(推荐) 是苹果...

    TableViewCellAutoLayoutDemo:iOS8 cell 自适应

    示例项目演示了iOS 8中的自调整表格视图单元格大小,使用UITableViewCell中的“自动布局”来实现具有可变行高的动态布局。 该项目是一个通用应用程序,将在iPhone和iPad上运行。 此实现仅与iOS 8及更高版本兼容。 ...

    iOS仿微博客户端一条微博的展示效果

    做一个微博客户端的第三方是自学的第一个实践的项目,自从从事iOS工作之后,就把这个项目给搁置了。趁现在过年回来有些空闲时间,再次修改(总觉得项目就是不停地修改)。并且记录一点东西,以后可再回头看看从前...

    Auto Layout获可变行高动态布局列表

    源码TableViewCellWithAutoLayoutiOS8,示例演示了在iOS 8中自动调整table view表格尺寸的功能,在UITableViewCell中使用Auto Layout来获得可变行高的动态布局。 该项目适用于iPhone和iPad,仅兼容iOS 8及以上系统...

    AutolayoutExampleWithMasonry:与Masonry不同的Autolayout示例。用砌体写的Autolayout案例,持续更新中。详细解答请看tutuge.me

    案例4:动态高度UITableViewCell,附加简单的高度缓存 Case5:topLayoutGuide和bottomLayoutGuide使用案例 案例6:自定义基准线效果 Case7:给UITableView加简单的视差视差效果标题 案例8:实时更改UITableViewCell...

    Styled TableViewCell(iPhone源代码)

     自定义列表 cell (UITableViewCell)的选中颜色(可增添渐变颜色),以及自定义cell和cell之间的分割线(separator)。 仅支持ARC模式。如果你的项目使用非ARC,则必须在编译模式中给此类库的所有代码加上:-...

    创建有多种cell的UITableView的方法

    · 加入了“高级评论”的示例代码,根据数据源数组来显示评论列表,个数不确定、评论内容长度不确定(即cell高度不确定),可在工程中搜索 高级评论 查看相关代码。 · 加入了cell上按钮触发事件绑定的示例代码,...

    FunctionalTableData:声明式UITableViewDataSource实现

    提供的HostCell泛型使向UITableViewCell添加FunctionalTableData支持变得容易。 值得注意的功能 :hundred_points: 维护表状态的功能方法 :construction_worker:‍ 可重用的视图和状态 :white_heavy_check_mark...

    ObjectForm:一个简单但功能强大的Swift库,可为您的类模型构建表单

    因此,我编写了ObjectForm,以使构建表单和绑定模型类变得非常简单。 ObjectForm不需要您编写UIKit代码。 通过设计,很容易理解和扩展。 如果仔细遵循示例项目,您会发现很容易将其放入Swift项目。 该项目不依赖...

    iphone3开发基础教程

    8.7.2 深层可变副本 169 8.7.3 更新控制器头文件 170 8.7.4 修改视图 171 8.7.5 修改控制器实现 173 8.8 小结 183 第9章 导航控制器和表视图 184 9.1 导航控制器 184 9.1.1 栈的性质 184 9.1.2 控制器栈 185 9.2 由...

Global site tag (gtag.js) - Google Analytics