** Note that this issue does NOT happen on ios 9 but on ios 10 only.
I have a collection view with cell called "MyCell". Each MyCell contains a MyView, and MyView contains a MyLabel. 2 seconds after the viewcontroller did load, I trigger a call "setNeedsLayout" to one of visibleCells of collectionView to refresh its MyLabel's content.
If my MyLabel's adjustsFontSizeToFitWidth is not set, it works ok. But if I assign adjustsFontSizeToFitWidth = true, app will hang up with an infinite number of calls to "layoutSubviews".
The sample code is as following (~120 lines). If I comment out line #18, it works ok but the font is not scaled as I expected. If I leave it as is, app will hang up and crash due to out-of-memory error.
Thanks for your help.
import UIKit import SnapKit class MyView: UIView { var myText: String = "" { didSet { self.setNeedsLayout() } } let myLabel = UILabel() override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.whiteColor() myLabel.adjustsFontSizeToFitWidth = true self.addSubview(myLabel) myLabel.snp_remakeConstraints { (make) in make.size.equalTo(CGSizeMake(200, 50)) make.center.equalTo(self) } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() self.myLabel.text = self.myText } } class MyCell: UICollectionViewCell { let myView = MyView() override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.darkGrayColor() self.addSubview(myView) myView.snp_remakeConstraints { (make) in make.center.equalTo(self) make.size.equalTo(CGSizeMake(210, 60)) } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func layoutSubviews() { super.layoutSubviews() self.myView.myText = "Hello!!!" } } class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { lazy var myCollectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .Vertical layout.minimumInteritemSpacing = 1.0 layout.minimumLineSpacing = 1.0 let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout) collectionView.dataSource = self collectionView.delegate = self collectionView.registerClass(MyCell.self, forCellWithReuseIdentifier: "MyCell") return collectionView }() let myButton = UIButton() override func viewDidLoad() { super.viewDidLoad() self.view.addSubview(myCollectionView) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2 * NSEC_PER_MSEC)), dispatch_get_main_queue(), { self.myCollectionView.visibleCells().last?.setNeedsLayout() }) } func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return 1 } func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 2 } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCellWithReuseIdentifier("MyCell", forIndexPath: indexPath) return cell } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { return CGSizeMake(self.view.bounds.width, self.view.bounds.height) } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat { return 0 } func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat { return 0 } }