在用 UICollectionView 写个标签浏览器,因为是自己实现的 FlowLayout,所以 UILabel 的大小需要自己获取,然后传给 UICollectionViewCell,网上看到的一个方法,使用 NSStringboundingRect(with:options:attributes:context:) 方法计算。

具体的代码如下:

extension NSString {
    func getSize() -> CGSize? {
        return self.boundingRect(with: CGSize(width: 500, height: CGFloat.greatestFiniteMagnitude), options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin], attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17)], context: nil).size
    }
}

刚开始写的时候没注意 attributes 设置,导致怎么写发现都不对,后来查了一下文档发现 UILabel 的默认字体大小是17 point,就加上了字体设置尝试一下,结果就对了。

参考3的文章是14年的一篇文章,虽然现在API的定义变了,但里面包含的概念还是正确的,Specifying the Space Between Items and Lines 那块儿建议着重看一下,基本讲清了 UICollectionViewFlowLayout 本身只是一个简单的实现,想要更灵活的布局还是需要自己去实现。

不得不说,iOS写布局真的费劲啊,一个普通的标签浏览器布局查文档、查StackOverflow写了一天,这点时间写前端都够我把整个页面+功能写完了。

参考

  1. boundingRect(with:options:attributes:context:)
  2. Dynamic Text Resizing in Swift
  3. Using the Flow Layout