UITableView-FDTemplateLayoutCell扩展开发:自定义高度计算逻辑

UITableView-FDTemplateLayoutCell扩展开发:自定义高度计算逻辑

【免费下载链接】UITableView-FDTemplateLayoutCell Template auto layout cell for automatically UITableViewCell height calculating 【免费下载链接】UITableView-FDTemplateLayoutCell 项目地址: https://gitcode.com/gh_mirrors/ui/UITableView-FDTemplateLayoutCell

引言

在iOS开发中,UITableView(表格视图)是常用的UI组件,用于展示列表数据。其中,动态计算单元格(Cell)高度是一个常见需求,尤其是当单元格内容不固定时。UITableView-FDTemplateLayoutCell是一个开源项目,旨在通过自动布局(Auto Layout)实现单元格高度的自动计算。本文将详细介绍如何扩展该项目,实现自定义高度计算逻辑,以满足复杂的业务需求。

项目概述

UITableView-FDTemplateLayoutCell项目提供了一套基于自动布局的单元格高度计算方案,支持通过重用标识符(Reuse Identifier)缓存和计算单元格高度。项目核心文件位于Classes/目录下,包括用于高度缓存的UITableView+FDIndexPathHeightCache.hUITableView+FDKeyedHeightCache.h,以及核心布局逻辑的UITableView+FDTemplateLayoutCell.hUITableView+FDTemplateLayoutCell.m

项目提供了两种高度缓存方式:基于索引路径(IndexPath)和基于键(Key)。基于索引路径的缓存适用于静态数据列表,而基于键的缓存则更适合动态数据,如根据数据模型的唯一标识符进行缓存。

核心原理

自动布局与自适配单元格

UITableView-FDTemplateLayoutCell的核心原理是利用iOS的自动布局机制,通过约束(Constraints)定义单元格内容与单元格边界之间的关系,使单元格能够根据内容自动调整高度。一个“自适配”(self-satisfied)的单元格需要满足每个边缘(上、左、下、右)至少有一个约束与父视图(通常是contentView)关联,确保内容能够垂直扩展。

自适配单元格示例

上图展示了一个正确配置的自适配单元格,所有边缘都有约束,内容能够根据文本长度自动调整高度。相比之下,下图中的单元格缺少右边缘和下边缘约束,无法正确计算高度。

非自适配单元格示例

高度计算流程

项目的高度计算主要通过fd_heightForCellWithIdentifier:configuration:方法实现。该方法的内部流程如下:

  1. 获取模板单元格:通过fd_templateCellForReuseIdentifier:方法获取或创建一个模板单元格,用于高度计算。
  2. 配置单元格内容:调用配置回调(Configuration Block),为模板单元格设置数据。
  3. 计算高度:调用fd_systemFittingHeightForConfiguratedCell:方法,利用自动布局计算单元格高度。

核心代码位于UITableView+FDTemplateLayoutCell.mfd_systemFittingHeightForConfiguratedCell:函数中,该函数通过添加宽度约束,强制内容垂直扩展,然后使用systemLayoutSizeFittingSize:计算高度。

自定义高度计算逻辑

场景分析

默认情况下,UITableView-FDTemplateLayoutCell使用自动布局计算高度。但在某些场景下,可能需要自定义高度计算逻辑,例如:

  • 单元格包含复杂视图,自动布局计算效率低下。
  • 需要根据特定业务规则动态调整高度,而非完全依赖内容。
  • 兼容旧项目中基于Frame的布局方式。

实现方式

1. 使用Frame布局模式

项目支持通过设置fd_enforceFrameLayout属性强制使用Frame布局模式,此时需要重写单元格的sizeThatFits:方法,手动计算高度。

// 在单元格配置块中设置强制Frame布局
cell.fd_enforceFrameLayout = YES;

// 在自定义单元格类中重写sizeThatFits:
- (CGSize)sizeThatFits:(CGSize)size {
    // 手动计算内容高度
    CGFloat contentHeight = self.titleLabel.frame.size.height + self.contentLabel.frame.size.height + 20; // 20为边距
    return CGSizeMake(size.width, contentHeight);
}
2. 扩展高度计算方法

通过分类(Category)扩展UITableView+FDTemplateLayoutCell,添加自定义高度计算方法。例如,添加一个支持额外内边距的高度计算方法:

// UITableView+FDTemplateLayoutCellCustom.h
#import "UITableView+FDTemplateLayoutCell.h"

@interface UITableView (FDTemplateLayoutCellCustom)
- (CGFloat)fd_heightForCellWithIdentifier:(NSString *)identifier insets:(UIEdgeInsets)insets configuration:(void (^)(id cell))configuration;
@end

// UITableView+FDTemplateLayoutCellCustom.m
#import "UITableView+FDTemplateLayoutCellCustom.h"

@implementation UITableView (FDTemplateLayoutCellCustom)
- (CGFloat)fd_heightForCellWithIdentifier:(NSString *)identifier insets:(UIEdgeInsets)insets configuration:(void (^)(id cell))configuration {
    CGFloat height = [self fd_heightForCellWithIdentifier:identifier configuration:configuration];
    return height + insets.top + insets.bottom;
}
@end
3. 自定义缓存策略

项目默认提供了基于IndexPath和Key的缓存策略。如果需要更复杂的缓存逻辑(如根据数据版本号缓存),可以扩展FDKeyedHeightCache类:

// FDVersionedKeyedHeightCache.h
#import "UITableView+FDKeyedHeightCache.h"

@interface FDVersionedKeyedHeightCache : FDKeyedHeightCache
- (void)cacheHeight:(CGFloat)height byKey:(id<NSCopying>)key version:(NSString *)version;
- (CGFloat)heightForKey:(id<NSCopying>)key version:(NSString *)version;
@end

// FDVersionedKeyedHeightCache.m
#import "FDVersionedKeyedHeightCache.h"

@implementation FDVersionedKeyedHeightCache
- (void)cacheHeight:(CGFloat)height byKey:(id<NSCopying>)key version:(NSString *)version {
    NSString *versionedKey = [NSString stringWithFormat:@"%@_%@", key, version];
    [self cacheHeight:height byKey:versionedKey];
}

- (CGFloat)heightForKey:(id<NSCopying>)key version:(NSString *)version {
    NSString *versionedKey = [NSString stringWithFormat:@"%@_%@", key, version];
    return [self heightForKey:versionedKey];
}
@end

调试与日志

项目提供了调试日志功能,通过设置fd_debugLogEnabledYES,可以打印高度计算过程中的关键信息,帮助排查问题:

self.tableView.fd_debugLogEnabled = YES;

日志输出示例:

** FDTemplateLayoutCell ** layout cell created - FDFeedCell
** FDTemplateLayoutCell ** calculate using system fitting size (AutoLayout) - 233.5
** FDTemplateLayoutCell ** cached by index path[0:0] - 233.5

实际应用示例

集成步骤

  1. 注册单元格:确保已通过Storyboard、Nib或代码注册单元格。
  2. 实现高度代理方法:在tableView:heightForRowAtIndexPath:中调用项目提供的高度计算方法。
  3. 配置单元格:在配置块中设置单元格内容,如需自定义高度,设置fd_enforceFrameLayout并实现sizeThatFits:

代码示例

// 注册单元格
[self.tableView registerClass:[FDFeedCell class] forCellReuseIdentifier:@"FDFeedCell"];

// 实现高度代理方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [tableView fd_heightForCellWithIdentifier:@"FDFeedCell" cacheByIndexPath:indexPath configuration:^(FDFeedCell *cell) {
        // 配置单元格数据
        cell.entity = self.feedEntities[indexPath.row];
        
        // 如需自定义高度,取消注释以下行并实现sizeThatFits:
        // cell.fd_enforceFrameLayout = YES;
    }];
}

性能优化

  1. 使用缓存:优先使用cacheByIndexPath:cacheByKey:方法,避免重复计算。
  2. 减少布局次数:在配置块中仅更新必要的UI属性,避免触发多次布局。
  3. 异步计算:对于复杂计算,可考虑在后台线程预计算高度并缓存。

总结与展望

UITableView-FDTemplateLayoutCell通过自动布局和缓存机制,简化了动态单元格高度的计算。通过扩展其高度计算逻辑,可以满足更复杂的业务需求。未来,可以进一步优化缓存策略,支持更灵活的高度计算规则,或集成SwiftUI以适应iOS开发新趋势。

官方文档:README.md 核心代码:Classes/ 示例项目:Demo/

【免费下载链接】UITableView-FDTemplateLayoutCell Template auto layout cell for automatically UITableViewCell height calculating 【免费下载链接】UITableView-FDTemplateLayoutCell 项目地址: https://gitcode.com/gh_mirrors/ui/UITableView-FDTemplateLayoutCell

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值