计算 NSString 高度以在 collectionView 单元格中使用
Posted
技术标签:
【中文标题】计算 NSString 高度以在 collectionView 单元格中使用【英文标题】:calculating NSString height to use in collectionView cells 【发布时间】:2017-12-28 16:07:35 【问题描述】:我正在尝试创建一个带有动态高度单元格的单列(一种 tableview 样式)的 collectionView。每个单元格将包含一个顶视图,其高度为 50 点,并具有单元格的前导、尾随和顶部约束。唯一的另一件事是下面的一些文本,它们将根据其内容具有动态高度。问题是我尝试使用 boundingRect 方法来计算标签的大小,但是如果文本太长,它将被切断(剪裁)并且单元格没有应有的高度。这是我的代码:
extension CustomCollectionViewController: UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let collectionViewWidth = collectionView.bounds.width
let topViewHeight: CGFloat = 50
let topAndBottomMargin: CGFloat = 8
let width = collectionViewWidth - 4 * 2
let text = answer[indexPath.item]
let s = NSString(string: "hello")
let font = UIFont.systemFont(ofSize: 15)
let height = calculateTextHeight(for: text, font: font, width: width - 100)
return CGSize(width: width, height: height + topViewHeight + topAndBottomMargin + 16)
func calculateTextHeight(for text: String, font:UIFont, width: CGFloat) -> CGFloat
let attributes = [NSFontAttributeName: font]
let estimateHeight = NSString(string: text).boundingRect(with: CGSize(width: width, height: .greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: attributes, context: nil)
let string = NSString(string: text)
//let estimateHeight = string.size(attributes: [NSFontAttributeName: font])
print(estimateHeight.height)
return CGFloat(ceil(estimateHeight.height))
第二件事是我仍然不明白 CGSize 中的宽度如何影响整体高度?
我尝试使用 NSString.size 但这根本不起作用。它严重低估了字符串的高度
【问题讨论】:
单元格中的文本在UILabel中? (你设置了最大行数吗?) 我将它设置为 0,这样它就可以拥有尽可能多的东西 宽度对高度的影响非常明显,因为宽度决定了你的文字是一、二、三行还是更多。 【参考方案1】:LayoutManager 将调用布局委托来获取项目大小(您实现的那个),但它只会执行一次,然后将此大小作为 layoutAttribute (UICollectionViewLayoutAttributes) 保存在缓存中。
所以也许在您的情况下它使用的是旧尺寸(在缓存中)并且您的集合视图已在两者之间调整了大小?
所以要做的一件事是在集合视图绑定更改时正确重置布局缓存(可能在 viewWillAppear 和 willTransition 中?) 在这种情况下,请执行以下操作:
let context = UICollectionViewFlowLayoutInvalidationContext()
context.invalidateFlowLayoutAttributes = true
context.invalidateFlowLayoutDelegateMetrics = true
self.collectionView.collectionViewLayout.invalidateLayout(with: context)
通过这样做,布局将清除缓存并要求您提供具有最新宽度的项目的正确宽度。如果您将每个项目设置为最大宽度,您将拥有一列
maxWidth = collectionView.bounds.width - layout.sectionInset.left - layout.sectionInset.right
【讨论】:
以上是关于计算 NSString 高度以在 collectionView 单元格中使用的主要内容,如果未能解决你的问题,请参考以下文章