I have moved collectionView to my ViewController, created IBOutlet, established connection with dataSource and delegate, added protocols: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, and also added methods:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection: (NSInteger)section
{
return 5;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (AdImageCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
AdImageCell *cell = (AdImageCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"AdImageCellIdentifier" forIndexPath:indexPath];
cell.imageView1.image = [UIImage imageNamed:#"3.jpg"];
return cell;
}
I also created custom cell and add this to viewDidLoad:
[self.collectionView registerNib:[UINib nibWithNibName:#"AdImageCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:#"AdImageCellIdentifier"];
But my problem here is that numberOfItemsInSection and numberOfSectionsInCollectionView is only called, but not cellForItemAtIndexPath. Why?
Sometimes it will work if you remove the collectionView registerClass:forCellWithReuseIdentifier from the viewDidLoad method.
collectionView:cellForItemAtIndexPath: never gets called
Hope it will help you..
Related
I am trying to make an app with CollectionView, but I'm facing a problem. As you can see from my code, I received the callback in both numberofSectionsINCollectionView and numberOfItemsInsection, but cannot receive the callback in cellForItemAtIndexPath, which makes the cell not show up inside CollectionView. However, with another computer with the same Xcode version and connected to the same iPhone (6 Plus), I can receive the callback in cellForItemAtIndexPath.
I don't know why. Could you please tell me how to fix the problem? I think it's attributed to the setting in Xcode, but I'm not sure.
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
if (self.useSection) {
return self.dataSource.count;
}
return 1;}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.useSection)
return [[self.dataSource objectAtIndex:section] count];
return self.dataSource.count; }
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:[self reuseIdentifierForIndexPath:indexPath] forIndexPath:indexPath];
return cell;
}
I double-checked if delegate is set like
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
cellForItemAtIndexPath won't be called if your cell size is (0,0) or count is 0 maybe you can try add this code :
- (CGSize)collectionView:(UICollectionView *)collectionView layout:
(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:
(NSIndexPath *)indexPath{ return CGSizeMake(100,100);}
How do I implement the layout showed in the image using UICollectionView?
Thanks in advance.
First:
- you have to create a UICollectionReusableView class for section:
ex: ReusableView.h
#interface ReusableView : UICollectionReusableView
#property (weak, nonatomic) IBOutlet UIImageView *headerImage; // example of header content
#end
ReusableView.m
#implementation ReusableView
- (void)awakeFromNib {
// Initialization code
}
#end
-in ReusableView.xib you have to delete the default view and add the UICollectionReusableView from ObjectLibrary and the you add your image or label or whatever and in AttributeInspector on identifier you have to write your IdentifierName (the same things you have to make for cell)
for cell you have to use the UICollectionTableViewCell class and follow the same steps from UICollectionReusableView.
Second:
in ViewController.h you have to use some delegates: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
in ViewController.m you have to use this methods from delegation, but first in viewDidLoad method you have to implement this:
[yourCollectionView registerNib:[UINib nibWithNibName:#"ReusableView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"CollectionReusable"]; //collection identifier is: #"CollectionReusable"
[yourCollectionView registerNib: [UINib nibWithNibName:#"CollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"CollectionCell"];
for section you have to implement this methods from delegate:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section
{
return CGSizeZero;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section; // here you return number of sections
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
headerView = nil;
headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"CollectionReusable" forIndexPath:indexPath];
[headerView.headerImage setImage:[UIImage imageNamed:[listOfSymbolsObjects objectAtIndex:indexPath.section]]];
return headerView;
}
-for cells you have to implement this methods from delegates:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
Hope it helps you ! :)
All,
I am adding a UICollectionView to a UIView but it's failing to load cells because it seems that this:
[self.buttonsCollectionView registerNib:[UINib nibWithNibName:#"AccountMenuCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"AccountMenuCell"];
Is getting loaded after it hits the delegates for the UICollectionView. Normally this would be placed in viewDidLoad but is not available in a UIView.
- (AccountMenuCollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
AccountMenuCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"AccountMenuCell" forIndexPath:indexPath];
[cell.accountMenuButton setTitle:#"Deposit" forState:UIControlStateNormal];
return cell;
}
Any guidance?
EDIT:
So I am using a view from the storyboard initially and then adding a subview which is Account Menu. Within this view I have a Collection View.
Try to use with the default method and instantiate your Cell inside of the cellForItem...
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
AccountMenuCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"AccountMenuCell" forIndexPath:indexPath];
[cell.accountMenuButton setTitle:#"Deposit" forState:UIControlStateNormal];
return cell;
}
and .. verify with Breakpoints if your code is running..
I am trying to add UICollectionViewControllers inside UIView class.
I cant add the controls.
CGRect viewframes=CGRectMake(0,400,self.view.bounds.size.width,
self.view.bounds.size.height/2);
self.button=[[view2 alloc]initWithFrame:viewframes];
self.button.backgroundColor=[UIColor grayColor];
[self.view addSubview:self.button];
Add UICollectionView control to your xib and set outlet of that and also add it's delegate methods UICollectionViewDataSource and UICollectionViewDelegate to .h file .
Add below code to your .m file
#pragma mark Collection View Methods
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(10, 10, 10, 10);
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [urlArray count];
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(140, 140);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
GalleryCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.tag=indexPath.row;
return cell;
}
If you are using custom cell and you want to reload Collection view than add below code
[YourCollectionview registerNib:[UINib nibWithNibName:#"GalleryCell" bundle:nil] forCellWithReuseIdentifier:#"cell"];
[YourCollectionview reloadData];
I create 2 UICollectionView classes, each one use 2 different UICollectionViewCell
#interface PhotosCollectionViewController : UICollectionViewController
#interface FullScreenCollectionViewController : UICollectionViewController
#interface PhotoCell : UICollectionViewCell
#interface FullPhotoCell : UICollectionViewCell<UIScrollViewDelegate>
In PhotosCollectionViewController.m, I register PhotoCell class and choose next view controller is FullScreenCollectionViewController when didSelect
//Register Cell
-(id)initWithCollectionViewLayout:(UICollectionViewFlowLayout *)layout{
if (self = [super initWithCollectionViewLayout:layout])
{
[self.collectionView registerClass:[PhotoCell class] forCellWithReuseIdentifier:CELL_ID];
}
return self;
}
//dequence resuse code
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCell* cell = (PhotoCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CELL_ID forIndexPath:indexPath];
NSLog(#"reuse CELL");
FICDPhoto *photo = [_photos objectAtIndex:indexPath.row];
cell.imageView.image = [photo sourceImage];
return cell;
}
//Next ViewController transition code
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *vc = [self nextViewControllerAtPoint:CGPointZero];
[self.navigationController pushViewController:vc animated:YES];
}
-(UICollectionViewController*)nextViewControllerAtPoint:(CGPoint)p
{
FullScreenCollectionViewController* nextCollectionViewController = [[FullScreenCollectionViewController alloc] initWithCollectionViewLayout:[[FullScreenFlowLayout alloc] init]];
nextCollectionViewController.useLayoutToLayoutNavigationTransitions = YES;
nextCollectionViewController.title = #"FullScreen";
return nextCollectionViewController;
}
In FullScreenCollectionViewController, I register FullPhotoCell class
[self.collectionView registerClass:[FullPhotoCell class] forCellWithReuseIdentifier:CELL_ID_FULL];
But sequence code never call
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
FullPhotoCell* cell = (FullPhotoCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CELL_ID_FULL forIndexPath:indexPath];
NSLog(#"Reuse FULL Cell");
FICDPhoto *photo = [_photos objectAtIndex:indexPath.row];
cell.imageView.image = [photo sourceImage];
return cell;
}
New layout is apply, viewDidload of FullScreenCollectionViewController also call, but the log message "reuse CELL" tell that fullScreen CollectionView still use old PhotoCell class.
I still don't understand what's problem. Please help me!
The answer is "a bit" late but this might be useful for someone else. When you use useLayoutToLayoutNavigationTransitions the collection view from the view controller initiating the transition is actually reused. This collection view has a different data source and delegate and that's why FullScreenCollectionViewController's cellForRowAtIndexPath is not being called. Take a look at this similar question:
UICollectionView UseLayoutToLayoutNavigationTransitions with different datasources