ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码
当前位置:首页 >> 网络编程 >> IOS开发 >> iOS 12 的坑:UICollectionViewCell autolayout self sizing 和 size

iOS 12 的坑:UICollectionViewCell autolayout self sizing 和 size(1/2)

来源:网络整理     时间:2018-10-25     关键词:

本篇文章主要介绍了" iOS 12 的坑:UICollectionViewCell autolayout self sizing 和 size",主要涉及到方面的内容,对于IOS开发感兴趣的同学可以参考一下: 好久好久不写博客了…… 一直在忙着搞公司的博客(做个小广告,欢迎关注:),把自己的博客荒废了 >问题表现iOS 12 发布之后,QA 开始给仓薯源源不断地...

好久好久不写博客了…… 一直在忙着搞公司的博客(做个小广告,欢迎关注:),把自己的博客荒废了 >< 但是最近遇到一个奇葩的 UI bug,非常无奈,当时在网上查了半天也没查到,所以在这记录一下。

问题表现

iOS 12 发布之后,QA 开始给仓薯源源不断地 assign UI 错乱的 bug。我想这是所有工程师都头疼的问题:几百年没改过的地方,突然就有人给你报 bug 了。测了一下,发现都是 iOS 12 特有的 bug,初步认定是苹果的锅。具体有以下几种症状:

  1. 之前用 estimated item size 的页面,比如说指定 estimated item size 高度是 80,但把真实数据填进去之后,self sizing 的 cell 真实高度是 100。所以正常应该显示高度为 100,之前都没问题。到了 iOS 12 之后,突然就不是 100 了,也不是 80 ,而是 60 多这样一个奇怪的数……

  2. 之前好好的 cell 突然消失了。看了下原因,是 systemLayoutSizeFitting(UILayoutFittingCompressedSize).height) 返回 0。本来 20 多、30 多的 cell 通通返回 0。

  3. debugger 里出来一大堆 constraint 冲突的 warning。仔细看一下,是多了一个莫名其妙的 constraint,不是我加的,不知道从哪里来,优先级还是 required。

能重现问题的 demo

下面是一个非常简单的 demo,能重现出这类 bug。假设我们有一个 SimpleCollectionViewCell,顾名思义,它是一个非常简单的 collectionViewCell。里面有个顶天立地的方块,充满这个 cell 的空间。

final class SimpleCollectionViewCell: UICollectionViewCell {
  override init(frame: CGRect) {
    super.init(frame: frame)
    let squareView = UIView(frame: .zero)
    contentView.addSubview(squareView)
    squareView.translatesAutoresizingMaskIntoConstraints = false
    squareView.heightAnchor.constraint(equalToConstant: 100).isActive = true
    squareView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
    squareView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
    squareView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    squareView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
  }
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }
}

所以这个 square 的高度为 100,四面 constraint 到 contentView。没什么问题吧?~ 下面我们用

systemLayoutSizeFitting 来算它的高度:

class ViewControllerUIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    let measurementCell = SimpleCollectionViewCell(frame: .zero)
    let cellWidth = view.frame.width
    measurementCell.widthAnchor.constraint(equalToConstant: cellWidth).isActive = true
    let size = CGSize(width: cellWidth, height: measurementCell.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height)
    print(size)
  }
}

size 打印出来是多少呢?在 iOS 11 上打印出来 (320, 100) 没问题。在 iOS 12 上打印出来就是 (320, 0) 了。

解决方法

Debug 的过程就懒得吐槽了。本以为是个很常见的问题,但在网上查了一圈没查到相关的东西,还以为是自己工程的问题,绕了一圈…… 最后解决方法也很简单:

  1. 忽略 contentView,直接把 subView 加到 cell 上。不用 contentView 在 UITableViewCell 里会有问题,在 collectionView 里似乎还没发现什么问题。

  2. 如果要用 contentView,需要在 init 里加几行:

相关图片

相关文章