ios - 计算在collectionView单元格中使用的NSString高度

标签 ios swift uicollectionview uicollectionviewcell

我正在尝试创建一个具有动态高度单元格的单列(一种表格 View 样式)的collectionView。每个单元格将包含一个高度为 50 点的顶 View ,并对单元格具有前导、尾随和顶部约束。唯一的另一件事是下面的一些文本,它将根据其内容具有动态高度。问题是我尝试使用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 但这根本不起作用。它严重低估了字符串的高度

最佳答案

LayoutManager 将调用布局委托(delegate)来获取项目大小(您实现的大小),但它只会执行一次,然后将此大小作为布局属性 (UICollectionViewLayoutAttributes) 保留在缓存中。

所以也许在你的情况下它使用的是旧的大小(在缓存中)并且你的 Collection View 在两者之间已经调整了大小?

所以要做的一件事是,当 Collection View 绑定(bind)更改时(可能在 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

关于ios - 计算在collectionView单元格中使用的NSString高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45257421/

相关文章:

iphone - 每次应用启动时仅调用一次方法

objective-c - 当 View 切换时,tabBar 消失。为什么?

ios - 文本字段中的边框和填充样式不适用于 swift5

swift - 为什么设置约束后无法再调整 NSWindow 的大小?

ios - 使用点击手势时如何获取 UICollectionView header 的索引路径?

ios - NSCollectionLayoutSupplementaryItem 显示在单元格下方

ios - UIButton,左边是文字,右边是图片

swift - 使用 Firebase 和 Swift 从未知的 child 名字中检索数据

swift - 为什么 Apple 选择使用嵌套结构类型来替换 'String' 类型参数?

ios - 当我运行应用程序时,CollectionView 不显示