RxCollectionViewSectionedAnimatedDataSource crash if estimatedItemSize was set in iOS 14.0&14.0.1
izhoubin opened this issue · comments
izhoubin commented
I have a problem here,and need your help.
- Use
RxCollectionViewSectionedAnimatedDataSource
- The property
estimatedItemSize
was set. - Use
NSLayoutConstraint
inUICollectionViewCell
- iOS 14.0 or iOS 14.0.1(as i known)
- Reload
It will always crash If the conditions above are met, in file 'RxCollectionViewSectionedAnimatedDataSource' at collectionView.performBatchUpdates(updateBlock, completion: nil)
in both simulators and phones.
Xcode :Version 13.4 (13F17a)
System: macOS 12.3.1 (21E258)
You can reproduce by the following code and click Reload
:
import UIKit
import RxDataSources
import RxCocoa
import RxSwift
class ViewController: UIViewController {
var collectionView:UICollectionView!
var dataSouce:RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int,String>>!
let items:BehaviorRelay<[String]> = BehaviorRelay(value:["1","2","3","4","5","6"])
let disposeBag:DisposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView()
setupReload()
setupRx()
}
func setupReload(){
let reloadButton = UIButton()
reloadButton.setTitle("Click here to reload", for: UIControl.State.normal)
reloadButton.setTitleColor(UIColor.black, for: UIControl.State.normal)
view.addSubview(reloadButton)
reloadButton.frame.size = CGSize(width: 200, height: 50)
reloadButton.center = view.center
reloadButton.addTarget(self, action: #selector(reload), for: UIControl.Event.touchUpInside)
}
@objc func reload(){
items.accept(items.value.shuffled())
}
func setupCollectionView(){
let layout = UICollectionViewFlowLayout()
//crash when reload if 'estimatedItemSize' is set in iOS 14.0 & 14.0.1
layout.estimatedItemSize = CGSize(width: 80, height: 50)
layout.minimumLineSpacing = 10
layout.minimumInteritemSpacing = 10
collectionView = UICollectionView(frame: UIScreen.main.bounds, collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.white
view.addSubview(collectionView)
collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
}
func setupRx(){
dataSouce = RxCollectionViewSectionedAnimatedDataSource<AnimatableSectionModel<Int,String>>(configureCell: {(dt, collectionView, indexPath, model) -> UICollectionViewCell in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell
cell.backgroundColor = UIColor.blue
cell.label.text = model
return cell
})
items
.map{[AnimatableSectionModel(model: 0, items: $0)]}
.bind(to:collectionView.rx.items(dataSource: dataSouce))
.disposed(by:disposeBag)
}
}
class CollectionViewCell: UICollectionViewCell {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(label)
label.textAlignment = .center
label.font = UIFont.systemFont(ofSize: 30)
label.backgroundColor = UIColor.yellow
contentView.backgroundColor = UIColor.purple
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: label, attribute: .left, relatedBy: .equal, toItem: contentView, attribute: .left, multiplier: 1, constant: 10).isActive = true
NSLayoutConstraint(item: label, attribute: .right, relatedBy: .equal, toItem: contentView, attribute: .right, multiplier: 1, constant: -10).isActive = true
NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: 10).isActive = true
NSLayoutConstraint(item: label, attribute: .bottom, relatedBy: .equal, toItem: contentView, attribute: .bottom, multiplier: 1, constant: -10).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}