UICollectionView with variant itemsize and multiple section - ios

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 ! :)

Related

UICollectionView Vertical showing half the cell in the end

i have collectionView. it shows cell in vertically.
in the start the collectionView looks like this
start of the collectionview
at the end it looks like this
end of collectionView
so it basically doesnt show up the whole cell in the end
the code for collection class is
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - CollectionView Datasource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 9;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
ViewControllerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
return cell;
}
#end
You have to specify the cell size in your storyboard.
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
float width = 100; //change to your needed width
float height = 100; //change to your needed height
return CGSizeMake(width, height);
}
try this code it will help you
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 9;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"cellIdentifier";
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
return cell;
}
and change identifier name in attribute inspector as shown in image:

How to add CollectionView to ViewController with storyboard?

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..

iOS app view choice

I want to develop an iOS app that takes all of the articles from my wordpress blog and lays them out properly. Every article has a title, an image and some content. For the first screen I want to make something like a customized UITableView, but I am not sure if this is the proper way to implement it.
http://a2.mzstatic.com/us/r30/Purple2/v4/5c/70/05/5c7005b2-ab76-33ab-e32f-5f7e861ef5e9/screen568x568.jpeg
Here is the kind of thing I want to do without the search bar. But every article would have its image layed out this way and the have its title (no need for a content preview) under the image. If I use a UITableView I will have a "separation" between all the images which is not exactly the way it is done here. Do you know how I could achieve something like this ? Would I have to create my graphical objects programmatically or is this feasible with the storyboard/interface builder tools?
You should use customized UITableViewCell. Here are the resources:
https://developer.apple.com/library/ios/documentation/userexperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
http://www.idev101.com/code/User_Interface/UITableView/customizing.html
http://www.appcoda.com/customize-table-view-cells-for-uitableview/
You can create CustomCell class with XIB that is inherited from UITableViewCell. We will just add category in tableview class .m file in following way. I think this is the easiest method which an be applied for custom cell creation.
#interface UITableViewCell(NIB)
#property(nonatomic,readwrite,copy) NSString *reuseIdentifier;
#end
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 30;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier=#"cell";
CustomCell *cell=[tableView dequeueReusableCellWithIdentifier:identifier];
if(cell==nil)
{
NSLog(#"New Cell");
NSArray *nib=[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell=[nib objectAtIndex:0];
cell.reuseIdentifier=identifier;
}else{
NSLog(#"Reuse Cell");
}
cell.lbltitle.text=[NSString stringWithFormat:#"Level %d",indexPath.row];
id num=[_arrslidervalues objectAtIndex:indexPath.row];
cell.slider.value=[num floatValue];
return cell;
}
#end
For this kind of thing, UICollectionView is the best. Exact same delegate as UITableView, just more flexible and configurable. You can have square cells, you can set cell width, you can scroll left or right etc. It is used in the screenshot above, and instagram etc. Here's how to implement it.
In .h :
#interface MyViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
In .m :
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
UICollectionView *myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, 320, 480) collectionViewLayout:flowLayout];
[myCollectionView setDelegate:self];
[myCollectionView setDataSource:self];
[myCollectionView setIndicatorStyle:UIScrollViewIndicatorStyleBlack];
[myCollectionView setScrollIndicatorInsets:UIEdgeInsetsMake(0, 0, 0, -4)];
[myCollectionView setBackgroundColor:[UIColor whiteColor]];
[myCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"CustomCell"];
[self.view addSubview:myCollectionView];
Then for the delegate methods:
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;

could not dequeue a view of kind: UICollectionElementKindCell with identifier

I have UICollectionView, but it seems that I set up everything right. But I get the error:
'could not dequeue a view of kind: UICollectionElementKindCell with identifier PeopleCellForList - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
My storybord:
My code is:
#interface PeopleCellForList : UICollectionViewCell
#end
#implementation PeopleCellForList
#end
#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return self.arrayPeople.count;
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"PeopleCellForList " forIndexPath:indexPath];
return cell;
}
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
}
#pragma mark – UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat width = 106;
CGFloat height = width;
if (indexPath.row % 3 == 2) {
width = 108;
}
return CGSizeMake(width, height);
}
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
I tried [self.collectionViewMain registerClass:[PeopleCellForList class] forCellWithReuseIdentifier:#"PeopleCellForList"] in viewDidLoad: (during that I tried to remove and not remove cell from storyboard), but that didn't help.
You have an extra space in #"PeopleCellForList "

How to set UICollectionView inside UIView

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];

Resources