Reputation: 3563
Only my second time using UICollectionView's and perhaps I have bitten off more than I can chew but nevertheless:
I am implementing a UICollectionView (myCollectionView) that uses custom UICollectionViewCell's that I have subclassed. The subclassed cells (FullReceiptCell) contain UITableView's and are the size of the viewcontroller. I am trying to allow for horizontal scrolling between the FullReceiptCells.
The subclassed UICollectionViewController that contains myCollectionView is being pushed on to a nav controller stack. Currently, myCollectionView loas and horizontal scrolling is enabled. However, no cells are visible. I have confirmed that
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
has run and is returning an integer greater than 0. I have also confirmed that myCollectionView's delegate and datasource are properly set in IB to the subclassed UICollectionViewController.
The method where the cells are to be loaded:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
is not being called.
Here is where I push the UICollectionViewController and my viewDidLoad method within that controller (NOTE: initWithBill is an override of the normal initializer):
In the prior ViewControllers .m file:
FullReceiptViewController *test = [[FullReceiptViewController alloc] initWithBill:currentBill];
test.title = @"Review";
[self.navigationController pushViewController:test animated:YES];
In FullReceiptViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self.myCollectionView registerClass:[FullReceiptCell class] forCellWithReuseIdentifier:@"FullReceiptCellIdentifier"];
self.myCollectionView.pagingEnabled = YES;
// Setup flowlayout
self.myCollectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[self.myCollectionViewFlowLayout setItemSize:CGSizeMake(320, 548)];
[self.myCollectionViewFlowLayout setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[self.myCollectionViewFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
self.myCollectionViewFlowLayout.minimumLineSpacing = 0;
self.myCollectionViewFlowLayout.minimumInteritemSpacing = 0;
[self.myCollectionView setCollectionViewLayout:myCollectionViewFlowLayout];
//testing to see if the collection view is loading
self.myCollectionView.backgroundColor = [UIColor colorWithWhite:0.25f alpha:1.0f];
Any clue as to why it is not being called?
Upvotes: 126
Views: 108392
Reputation: 2082
Below is my observation:
if sizeForItemAt method of UICollectionViewDelegateFlowLayout returns 0 size then cellForItemAt will not call.
So collection view will not show up.
Upvotes: 1
Reputation: 7612
reloadSections
instead of reloadData
did it for me.
I don't know why reloadData
did not work.
Upvotes: 1
Reputation: 86
i) Please make sure to add the UICollectionView to UITableViewCells contentView and not as subView
Upvotes: 0
Reputation: 3684
In my case, I found workaround by this:
//IF RELOAD COLLECTION VIEW AFTER DELAY IT WORKS
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
//ASSIGN NEW DATA SOURCE
self.arrItem = arrModel
self.collectionView.reloadData()
}
Upvotes: -1
Reputation: 3303
In my case I had the collectionView
in a UIStackView
with alignment = .center
. So the collectionView
did not have a width. When setting the stackView.alignment
to .fill
everything was fine.
Upvotes: 6
Reputation: 790
I was having a similar problem. But instead cellForItemAtIndexPath
was called when the number of items was > 1, but not when there was only a single item. I tried many of the proposed solutions here and similar to many I found that it had to do with item sizing. For me the solution was to change the estimate size of the UICollectionView
from Automatic to Custom.
Upvotes: 7
Reputation: 1
In my case I had to adjust the estimated Content size. content size did not do it.
let layout = collectionVC.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: 100, height: 100)
layout.estimatedItemSize = CGSize(width: 100, height: 100)
Upvotes: 0
Reputation: 4870
If you're using collection view protocols you must connect the CollectionViewDataSource
and CollectionViewDelegate
protocols to your ViewController.
Upvotes: 3
Reputation: 334
In storyboard/xib UICollectionView property cellSize MUST not be {0, 0}
Upvotes: 3
Reputation: 10299
If your class is subclass from UICollectionviewController and you are creating collectionView programmatically then use
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .Vertical
layout.itemSize = CGSizeMake(50, 50)
collectionView?.setCollectionViewLayout(layout, animated: false)
Upvotes: 15
Reputation: 16552
In my case the collection view was not fully visible in its parent view due to wrong auto layout constraints. So fixing the constraints made the collection view all visible and cellForItemAtIndexPath was called.
Upvotes: 2
Reputation: 12198
I was using autolayout, and in my case height constraint was missing
Upvotes: 12
Reputation: 744
It can be realated layout problems. Check layout warnings from console, if exist.
Upvotes: 2
Reputation: 6170
When using UICollectionViewDelegateFlowLayout
be careful on what this function returns. Both width
and height
should be greater than 0
. I used window
as frame reference but due to complicated view hierarchy window was nil
at runtime. If you need adjust the width of the element based on screen width use UIScreen.main.bounds
.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout:
UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}
Upvotes: 2
Reputation: 131
My issue was that I had 2 collection views within the same view, and both were sharing a computed UICollectionViewFlowLayout
instance. Once I created separate instances of the same flow layout, it worked fine.
Upvotes: 6
Reputation: 955
Just resolved this issue, for a somewhat specific situation.
In my case, I was manually initializing the UICollectionViewController in a parent ViewController, and then adding the UICollectionViewController's view as a subview.
I resolved the issue by calling 'setNeedsLayout' and/or 'setNeedsDisplay' on the collectionView in the parent's viewDidAppear:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[_collection.view setNeedsLayout];
[_collection.view setNeedsDisplay];
}
Upvotes: 1
Reputation: 2608
For me, I update the height of self.view (the collectionView's superview) via autolayout, and MUST call layoutIfNeeded
after that.
[self.view mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@(height));
}];
[self.view layoutIfNeeded];
Upvotes: 2
Reputation: 804
In my case, set collectionView.prefetchingEnabled = NO;
solved my problem.
Only works on iOS 10.
Upvotes: 5
Reputation: 542
Also, make sure that reloadData is not called while collection view is updating with animation (insert, delete, update or performBatchUpdates).
Upvotes: 5
Reputation: 547
I forgot to set the autoresizing mask to false on the collection view:
collectionView.translatesAutoresizingMaskIntoConstraints = false
Upvotes: 5
Reputation: 28463
In my case, it was because my layout class incorrectly subclassed from UICollectionViewLayout
instead of UICollectionViewFlowLayout
Upvotes: 121
Reputation: 7606
I sunk a bit of time with this issue coming op with a CollectionView in a Contained view controller loaded from a storyboard. I ended up just deleting the contained view controller, and recreating it in the storyboard, and this seemed to get rid of the issue. My guess is there was some kind of storyboard corruption that had taken place.
Upvotes: -1
Reputation: 954
For a more complicated view hierachy please check this blog. It saved my life!
self.automaticallyAdjustsScrollViewInsets = NO;
Upvotes: 18
Reputation: 1838
Setting collectionView frame inside custom cell's layoutSubViews() worked for me:
override func layoutSubviews() {
super.layoutSubviews()
let frame = self.contentView.bounds
self.CollectionView.frame = frame
}
Upvotes: -2
Reputation: 4862
In Xcode 7.0.1, we got this problem when we copied a storyboard and accompanying code from another project. The collection view had a custom flow layout set in the storyboard. Solution was to:
Now it worked :)
Upvotes: 3
Reputation: 361
In my case, changing UINavigationBar's translucent to NO solved the problem.
Upvotes: 3
Reputation: 2352
Ten minutes ago I also encountered this problem, I made a silly mistake.
My intention is to use UICollectionViewFlowLayout,
But because of mistakes, I used UICollectionViewLayout.
Upvotes: 4
Reputation: 74
Make sure -(NSInteger) collectionView:numberOfItemsInSection: is returning a positive (read, greater than zero) value. It may be a matter of placing [self.collectionView reloadData]; in the completion handler.
Upvotes: 2
Reputation: 969
Make sure numberOfSectionsInCollectionView
returns a positive integer as well.
There has to be at least one section in the collection.
Upvotes: 2
Reputation: 403
Same happened to me. I had 2 UICollectionViews and I removed once since I didn't need that. After that I realised that the CellForItemAtIndexPath was not getting called but the other required methods. I tried all of the above but then I did the standard magic. Removed the collection view from storyboard and added again. Then it started working. Not sure why and I have no explanation but maybe some connection issues.
Upvotes: 1