-2

I want to make a left-aligned self-sizing collectionView just like this one:

enter image description here

and here is my sample project: https://github.com/DiaobaoMiaoo/LeftAlignedSelfSizingCollectionView

After running the project, rotate the device from portrait to landscape, then press the red button. Then the app will crash seemingly from layoutAttributesForElements with log:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack: 

Any idea what is the cause and how to fix this issue? Thanks!

I have also tried other approaches I found online to achieve the left aligned CollectionView including:

Left Align Cells in UICollectionView

https://github.com/mokagio/UICollectionViewLeftAlignedLayout

https://github.com/mischa-hildebrand/AlignedCollectionViewFlowLayout

But they all share the same issue that if the content of the cell is much longer than collectionView.framce.width, then the app will freeze with the console spammed on iOS11.

Ke MA
  • 761
  • 12
  • 30

2 Answers2

1

The problem is the layout constraint in your Chip cell. I recommend you to implement a clean way so you can track when Layout Constrains are created and stored and cleared on rotation since the cell layout is dependent on the parent. But for now hopefully this will solve your crash and gives you the lead to achieve your goal.

class ChipCell: UICollectionViewCell {

    var text: String? {
        didSet {
            label.text = text
        }
    }

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

        backgroundColor = .lightGray
        layer.cornerRadius = 2.0
        layer.masksToBounds = true

        addSubview(label)
        label.topAnchor.constraint(equalTo: topAnchor, constant: 2.0).isActive = true
        label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 2.0).isActive = true
        // label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0.0).isActive = true
        // label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0.0).isActive = true

    }

    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override open var intrinsicContentSize: CGSize {
        return CGSize(width: label.intrinsicContentSize.width + 4,
                      height: label.intrinsicContentSize.height + 4)
    }

    private let label: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textAlignment = .center
        label.textColor = .black
        return label
    }()
}
Amir.n3t
  • 2,859
  • 3
  • 21
  • 28
0

In ViewController add following method and it will working fine without crash.

override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        container.viewModel = viewModel
    }

Reason of the crash is while rotating your collectionView layout in not invalidated due to this crash occurs.

Pravin Tate
  • 1,145
  • 8
  • 18