Hi All - First time posting, hope I'm not breaking too many rules or protocols.
I'm trying to gain more experience with Collection Views to replace a Table View in one of my apps - it looks so simple, but I'm runnng into problem after problem. Most I can solve, but this one completely eludes me. It seems like it would be pretty straight forward, but apparently not.
UICollectionView in a UIView, UICollectionViewCell - main.storyboard view & simulator view
(Well, I actually pasted an image large enough to be easily viewable, but it appears, that's not an option. So here's a Dropbox link:
https://www.dropbox.com/s/34fvfhzipo0q00l/ScreenCaptures%4050%25.jpg?dl=0 )
The app appears to start off working normally and as expected, then after scrolling past cell #11 (of 25), it seems to completely lose its layout as you can see in the right side of the above graphic. Scrolling upward, it's even more wonky, all the cells turn into a full size image.
All cell insets and such are defined as zero as to not contribute to the problem.
During this "weirdness" the debugger begins pumping out message after message:
My debug messages for cells 11 & 12 from "override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {)" seem consistent.
// My debug messages ... for cells 11, 12, & 13
indexPath.item: 11
view.bounds: (0.0, 0.0, 414.0, 736.0)
collectionView.bounds: (0.0, 169.66666666666666, 414.0, 736.0)
collectionView.contentInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
collectionView.alignmentRectInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
layoutAttributesForItem: Optional(<UICollectionViewLayoutAttributes: 0x7fe495315500> index path: (<NSIndexPath: 0x8fc82db6ba53fbc9> {length = 2, path = 0 - 11}); frame = (214 968; 192 192); )
indexPath.item: 12
view.bounds: (0.0, 0.0, 414.0, 736.0)
collectionView.bounds: (0.0, 355.0, 414.0, 736.0)
collectionView.contentInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
collectionView.alignmentRectInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
layoutAttributesForItem: Optional(<UICollectionViewLayoutAttributes: 0x7fe495309740> index path: (<NSIndexPath: 0x8fc82db6bab3fbc9> {length = 2, path = 0 - 12}); frame = (8 1160; 192 192); )
indexPath.item: 13
view.bounds: (0.0, 0.0, 414.0, 736.0)
collectionView.bounds: (0.0, 355.0, 414.0, 736.0)
collectionView.contentInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
collectionView.alignmentRectInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
layoutAttributesForItem: Optional(<UICollectionViewLayoutAttributes: 0x7fe495302230> index path: (<NSIndexPath: 0x8fc82db6ba93fbc9> {length = 2, path = 0 - 13}); frame = (214 1160; 192 192); )
// Debugger Messages when things start going downhill ...
2019-10-22 01:32:54.794032-0500 CollectionTest#1[13173:339022] The behavior of the UICollectionViewFlowLayout is not defined because:
2019-10-22 01:32:54.794203-0500 CollectionTest#1[13173:339022] the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values.
2019-10-22 01:32:54.794360-0500 CollectionTest#1[13173:339022] Please check the values returned by the delegate.
2019-10-22 01:32:54.794856-0500 CollectionTest#1[13173:339022] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7fe4c1407750>, and it is attached to <UICollectionView: 0x7fe492819400; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = LM+W+RM+TM+H+BM; gestureRecognizers = <NSArray: 0x600000965050>; layer = <CALayer: 0x60000076efe0>; contentOffset: {0, 355}; contentSize: {414, 2512}; adjustedContentInset: {20, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x7fe4c1407750>.
2019-10-22 01:32:54.801289-0500 CollectionTest#1[13173:339022] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.
This just goes on and on ... abbreviated for brevity.
// My debug messages from "func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {)" seem to be consistent with all the cells before and after
width[10]: 414.0
cellDimension[10]: 192.0
returnSize[10]: (192.0, 192.0)
view.bounds: (0.0, 0.0, 414.0, 736.0)
collectionView.bounds: (0.0, -20.0, 414.0, 736.0)
collectionView.alignmentRectInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
collectionView.contentInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
width[11]: 414.0
cellDimension[11]: 192.0
returnSize[11]: (192.0, 192.0)
view.bounds: (0.0, 0.0, 414.0, 736.0)
collectionView.bounds: (0.0, -20.0, 414.0, 736.0)
collectionView.alignmentRectInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
collectionView.contentInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
width[12]: 414.0
cellDimension[12]: 192.0
returnSize[12]: (192.0, 192.0)
view.bounds: (0.0, 0.0, 414.0, 736.0)
collectionView.bounds: (0.0, -20.0, 414.0, 736.0)
collectionView.alignmentRectInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
collectionView.contentInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
width[13]: 414.0
cellDimension[13]: 192.0
returnSize[13]: (192.0, 192.0)
view.bounds: (0.0, 0.0, 414.0, 736.0)
collectionView.bounds: (0.0, -20.0, 414.0, 736.0)
collectionView.alignmentRectInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
collectionView.contentInset: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0)
width[14]: 414.0
I've modeled my code after the best examples I've been able to find, and thought I had solved the constraints problems - I think that's what's causing the problems, but no matter how I define the constraints, even in a stack view, this seems to always happen.
The code is pretty straight forward, so I'll save you some reading and only post what I think is the most suspect, if addition code is required, I'm happy to post it.
//Maybe should have picked a different name for my CollectionViewCell class, but it is descriptive.
CollectionViewCell.swift
import UIKit
class CollectionViewCell: UICollectionViewCell {
@IBOutlet weak var cellImage: UIImageView!
@IBOutlet weak var cellLabel: UILabel!
}
ViewController.swift
import UIKit
class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 25
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
cell.cellImage.image = UIImage(named: "file-35")
cell.cellLabel.text = "cell# \(indexPath.item)"
cell.layer.borderWidth = 0.5
cell.layer.borderColor = UIColor.lightGray.cgColor
cell.layer.cornerRadius = 10
cell.backgroundColor = UIColor.black
cell.cellImage.layer.cornerRadius = 10
print("indexPath.item: \(indexPath.item)")
print("view.bounds: \(view.bounds)")
print("collectionView.bounds: \(collectionView.bounds)")
print("collectionView.contentInset: \(collectionView.contentInset)")
print("collectionView.alignmentRectInsets: \(collectionView.alignmentRectInsets)")
print("layoutAttributesForItem: \(String(describing: collectionView.layoutAttributesForItem(at: indexPath)))")
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
collectionView.delegate = self
collectionView.dataSource = self
// view.translatesAutoresizingMaskIntoConstraints = true
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.item > 10 {
print("view.bounds: \(view.bounds)")
print("collectionView.bounds: \(collectionView.bounds)")
// collectionView.bounds = view.bounds
print("collectionView.alignmentRectInsets: \(collectionView.alignmentRectInsets)")
print("collectionView.contentInset: \(collectionView.contentInset)")
}
let width = view.bounds.width
print("width[\(indexPath.item)]: \(width)")
let cellDimension = (width / 2 ) - 15
print("cellDimension[\(indexPath.item)]: \(cellDimension)")
let returnSize = CGSize(width: cellDimension, height: cellDimension)
print("returnSize[\(indexPath.item)]: \(returnSize)")
return returnSize
}
}
It just seems so "odd" that the 1st screen of cell display as expected, then when it starts reusing cells, it's lost all its layout.
Thank you in advance for any solutions.