Since my move to the new iOS9 and Xcode 7 I have stumbled upon an issue with one of the UICollectionView
in my app.
Apparently, the UICollectionView
doesn't seem to update the UICollectionViewCell
layout and constraints properly, only until it is reused.
Pictures speak better than words -- this is how it looks like when the UIViewController
is first seen:
However this isn't the correct layout, and easily enough when I swipe the UICollectionView
horizontally to the left, I get the right layout of the newly appeared cells:
When I swipe back, the old cells that weren't correct, are now reused and look good.
Now, as it was prior to upgrading to iOS9 and Xcode 7, my wanted effect is that the cells have the correct layout even when first appearing.
For your convenience, here are more details on how the UICollectionView
is set up and it's constraints in the XIB:
In the code, it is pretty standard:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell : MatchmakersCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionCell", forIndexPath: indexPath) as! MatchmakersCollectionViewCell
cell.imageView.backgroundColor = UIColor.lightGrayColor()
cell.bottomName.text = "StackOverflow"
return cell
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.matchmakers.count
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
And every time I updated the datasource (self.matchmakers), I called self.collectionView.reloadData()
One last thing I had noticed which was very strange, when debugging with Xcode the debug view hierarchy, the UICollectionViewCell
never presented the subviews properly and just gave me a default UIView
in their stead:
To solve this problem:
Creat your custom UICollectionViewCell using Nib(.xib) files.
In your custom UICollectionViewCell ,override didMoveToSuperView() method to add this
self.setNeedLayout()
self.layoutIfNeeded()
3.In your UIViewController viewDidLoad() method
self.collectionView.registerNib(UINib(nibName: "yourNibName", bundle: nil), forCellWithReuseIdentifier: "Cell")
--------update 20150923
just need step 2, override didMoveToSuperView method to add
self.setNeedLayout()
self.layoutIfNeeded()
in your custom UICollectionViewCell class.
Thanks @macayer
I didn't have to create my own XIB for my cell, as long as I have my custom cell and have it linked into my storyboard, I just added those line in (MyCustomCollectionViewCell.m):
- (void)didMoveToSuperview{
[super didMoveToSuperview];
[self setNeedsLayout];
[self layoutIfNeeded];
}
I had same bug in iOS9 too. Perhaps you've found that it's all ok after you reloaded the collection view. So my solution: set a timer for iOS9 to reload the cells.
if #available(iOS 9, *) {
self.refreshTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("refreshDataTimer"), userInfo: nil, repeats: true)
}
And reload them :
func refreshDataTimer(){
self.collectionView?.reloadData()
}
Even though this solution is little stupid but it works in few lines.
or you can reload each cell :
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
....
self.collectionView?.reloadItemsAtIndexPaths([indexPath])
return cell
}
But it's inefficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With