iOS 12 的坑:UICollectionViewCell autolayout self sizing 和 size 计算失效了

栏目: IOS · 发布时间: 6年前

内容简介:好久好久不写博客了…… 一直在忙着搞公司的博客(打个小广告,欢迎关注:),把自己的博客荒废了 >< 但是最近遇到一个奇葩的 UI bug,非常无奈,当时在网上查了半天也没查到,所以在这记录一下。iOS 12 发布之后,QA 开始给仓薯源源不断地 assign UI 错乱的 bug。我想这是所有工程师都头疼的问题:几百年没改过的地方,突然就有人给你报 bug 了。测了一下,发现都是 iOS 12 特有的 bug,初步认定是苹果的锅。具体有以下几种症状:下面是一个非常简单的 demo,能重现出这类 bug。假

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

问题表现

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

systemLayoutSizeFitting(UILayoutFittingCompressedSize).height)

能重现问题的 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 ViewController: UIViewController {

  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 上。不用 contentViewUITableViewCell 里会有问题,在 collectionView 里似乎还没发现什么问题。
  2. 如果要用 contentView ,需要在 init 里加几行:
final class SimpleCollectionViewCell: UICollectionViewCell {

  override init(frame: CGRect) {
    super.init(frame: frame)

    contentView.translatesAutoresizingMaskIntoConstraints = false
    contentView.topAnchor.constraint(equalTo: topAnchor).isActive = true
    contentView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    contentView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
    contentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

    let squareView = UIView(frame: .zero)
    ...
  }
}
复制代码

看到这里,这个 bug 的原因就不言自明了……实在令人无语,为啥 iOS 12 会有这样一个改动呢。 不知道为啥,此前在网上都没有查到相关的内容,因此在这记录一下,希望能有帮助。


以上所述就是小编给大家介绍的《iOS 12 的坑:UICollectionViewCell autolayout self sizing 和 size 计算失效了》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深度探索C++对象模型

深度探索C++对象模型

斯坦利•B.李普曼 (Stanley B. Lippman) / 侯捷 / 电子工业出版社 / 2012-1 / 69.00元

作者Lippman参与设计了全世界第一套C++编译程序cfront,这本书就是一位伟大的C++编译程序设计者向你阐述他如何处理各种explicit(明确出现于C++程序代码中)和implicit(隐藏于程序代码背后)的C++语意。 本书专注于C++面向对象程序设计的底层机制,包括结构式语意、临时性对象的生成、封装、继承,以及虚拟——虚拟函数和虚拟继承。这本书让你知道:一旦你能够了解底层实现模......一起来看看 《深度探索C++对象模型》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具