UICollectionView Header xib not showing - ios

I have a collectionview and I want to use a xib as the header. However, the xib will not appear. First I tried adding a label to the xib, which didn't appear. Then I set the whole background color to red. It it doesn't appear. The collectionview items leave a gap for the header, but it's completely blank. Similar SO threads are this and this, but as I'm not using storyboards and my header height is greater than zero, they don't solve my issue. Here is all my relevant code:
#import "ScoreboardCollectionViewController.h"
#import "ScoreboardCollectionViewCell.h"
#import "ScoreboardReusableView.h"
#import "ScoreboardModel.h"
#import "Scoreboard.h"
...
- (void)viewDidLoad {
[super viewDidLoad];
// Register cell classes
UINib *cellNib = [UINib nibWithNibName:#"ScoreboardCollectionViewCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cell"];
[self.collectionView registerClass:[ScoreboardReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"scoreboardHeader"];
self.collectionView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"dark_fish_skin_"]];
}
...
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(self.view.frame.size.width, 34);
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath {
ScoreboardReusableView *view = [[ScoreboardReusableView alloc] init];
view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:#"scoreboardHeader"
forIndexPath:indexPath];
return view;
}
Here is a screenshot of my xib:

OK, I solved it. The problem was that in my viewDidLoad method I had
[self.collectionView registerClass:[ScoreboardReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"scoreboardHeader"];
when since I was using a nib, it should have been:
[self.collectionView registerNib:[UINib nibWithNibName:#"ScoreboardReusableView" bundle:nil]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:#"scoreboardHeader"];

I was missing "Section Header" option of Collection View to enable:-

Related

UICollectionView appears blank - cells don't show

I've setup a UICollectionView with a custom cell XIB. I've setup the delegate, data source methods appropriately but upon loading the collection view appears blank with a black screen:
Here is my code for registering the custom xib cell:
[self.collectionView registerClass:[CustomViewCell class] forCellWithReuseIdentifier:#"cvCell"];
Delegate/data source methods:
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 2;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 4; }
-(CustomViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cvCell";
CustomViewCell *cell = (CustomViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
I've also set the class for the custom xib cell:
EDIT:
Collection view layout is set to:
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(50, 29)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.collectionView setCollectionViewLayout:flowLayout];
The 50,29 refer to the size of the actual custom view xib cell
You should register your custom cell's nib instead of class.
UINib *cellNib = [UINib nibWithNibName:#"cvCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cvCell"];

UICollectionView header is called only once on the first cell

I am implementing a header for my UICollectionView right now, and I am struggling right now since the header is called only once on the first cell.
This is what I've done - I declared UICollectionViewFlowLayout to programmatically make a UICollectionView - in this case, pickView. And then I added two xib files - one for cell, and the other one for header. I have registered those files into collection view like this:
UICollectionViewFlowLayout *layout2 = [[UICollectionViewFlowLayout alloc] init];
self.pickView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, pointView_y, pointView_width, pointView_length) collectionViewLayout:layout2];
self.pickView.backgroundColor = [UIColor whiteColor];
[self.pickView registerNib:[UINib nibWithNibName:#"TodayCollectionViewCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:#"TodayCollectionViewCell"];
[self.pickView registerNib:[UINib nibWithNibName:#"PickCollectionReusableView" bundle:[NSBundle mainBundle]] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"PickCollectionReusableView"];
//layout2.headerReferenceSize = CGSizeMake(_screenWidth, 50);
[self.pickView setDataSource:self];
[self.pickView setDelegate:self];
[self.view addSubview:self.pickView];
And then I declared the size of header view like this:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
return CGSizeMake([Util screenWidth], 50);
}
And finally I called viewForSupplementaryElementOfKind to call header files like this:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
PickCollectionReusableView *reusableview = (PickCollectionReusableView*) [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"PickCollectionReusableView" forIndexPath:indexPath];
PickCellVariable *buf = (PickCellVariable*) _pickArray[indexPath.row];
NSLog(#"buf id = %#, SECTION = %lu", buf.itemID, (long)indexPath.row);
if(buf != nil) {
//reusableview.thumbPic = ;
[reusableview.brandName setTitle:[NSString stringWithFormat:#"%lu", (long)indexPath.row] forState:UIControlStateNormal];
[[reusableview brandName] setBrandName:buf.brandname];
[[reusableview brandName] addTarget:self action:#selector(brandClick:) forControlEvents:UIControlEventTouchUpInside];
[[reusableview settingButton] addTarget:self action:#selector(setting:) forControlEvents:UIControlEventTouchUpInside];
return reusableview;
}
else {
[[reusableview brandName] setBrandName:#""];
return reusableview;
}
}
I put the breakpoint and added NSLog line to make sure that viewForSupplementaryElementOfKind is only called once, in the very first cell.
I've tried to find cases like mine, but most of the issues regarding the UICollectionView header is when they registered class instead of registering xib file, or they forgot to set the size of header view. Mine is only called for once so this is not about overlap as well. My collection view is programmatically made so I do not redefine anything right now.
What could be the issue? Please, anything can help in here.
Thank you.
Ok, so my problem was that I called my data on row basis. However, in order to make header to appear on every cell, you have to call your data in section basis.
I hope no one is struggling anymore like me in terms of this issue.

Collection view is crashing for some reason

//collection view
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
self.collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[self.collectionView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:self.collectionView];
}
- (NSInteger)collectionView:(UICollectionView *)tcollectionView numberOfItemsInSection:(NSInteger)section
{
return 15;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor=[UIColor greenColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(50, 50);
}
crash on :
-[NSISUnrestrictedVariable collectionView:numberOfItemsInSection:]: unrecognized selector sent to instance 0x7fce804111b0
What is that ?
(the collection view is inside a view controller,tand he is inside a scrollview)
It looks like your UICollectionView has been deallocated from memory but you are still trying to access it.
Enable NSZombies and you'll see where you make the call to the deallocated memory and fix the code accordingly.
Found the solution . As mentioned here, the collection view is deallocated from memory.
Reason is because that view controller that holds it, is inside a scrollview, and i didn't create it a property as strong to retain it , so :
//the view controller that holds the collection
#property(nonatomic,strong) BlisterView *blister;
solves the problem.

UICollectionView Footer not showing

I am trying show footer on collection view. In my story board i set accessory as footer in UICollectionView and i took collection reusable view.
[self.cv registerClass:[ItemFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:#"FooterView"];//in view did load
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
ItemFooterView *footerView=[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:#"FooterView" forIndexPath:indexPath];
return footerView;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section
{
return CGSizeMake(50, 50);
}
still footer not showing if any suggestions on this.
UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init];
layout.footerReferenceSize = CGSizeMake(300, 60);
make sure you have set the size for the footer
I think you forgot to register class/nib for the footer view. Do this in viewDidLoad
[self.collectionView registerClass:[FooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:#"FooterView"];

iOS UICollectionView: Cells not showing

I'm missing something obvious here as this isn't a difficult task.
I have my Collection view in storyboard (amongst other views), with the prototype cell's reuse id being "Cell", and a UILabel in that cell, with a tag of 100.The code (boilerplate):
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 4;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
UILabel *label = (UILabel *)[cell viewWithTag:100];
label.text = #"Hello";
return cell;
}
The code is within a UICollectionViewController, as it should.
When i run, the view appears yet no cells or text are visible.
A NSLog in the cellForItemAtIndexPath confirms that it is called, 4 times.
I've even changed the prototype cell's background color which shows that not even the cell's are appearing.
In the viewDidLoad, it calls: [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
What am i missing?
Use like this:
Instead of registerClass: use registerNib:
static NSString *identifier = #"Cell";
if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPhone) {
[self.collection registerNib:[UINib nibWithNibName:#"CollectionPhotoItem" bundle:nil] forCellWithReuseIdentifier:identifier];
}
else{
[self.collection registerNib:[UINib nibWithNibName:#"CollectionPhotoItem_ipad" bundle:nil] forCellWithReuseIdentifier:identifier];
}
make sure you are under any-any ratio in your storyboard
if you are working with any other configuration and you tried to use the simulation it might not show up
for example if you use regular width and compact hight and then tried to use the simulator in your Xcode all your work will not show up !

Resources