UICollectionViewCell With Dynamic Size Cell Spacing Issue - ios

I'm Creating Custom UICollectionViewCell it's size automatically set from it's Content.
The Dynamic Size of cell is Working But In That It Have Extra Space.
So I Want to remove extra Space Between Two Cell
I'm also set UICollectionView DataSource and Delegate and Impalement It's Method But Still it is not Working
In One Row not fix their only 2 cell. It have 1, 2, or 3 cell it's depend on Text
CustomeCollectionViewCell.m
- (CGSize)intrinsicContentSize
{
CGSize size = self.lblText.intrinsicContentSize;
size.width += 48; // add padding Width that Given in Cell
size.height += 32; // add padding Height
return size;
}
ViewController.m
#interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
#property (strong, nonatomic) CustomeCollectionViewCell *tempCell;
#property (strong, nonatomic) NSArray *dataArr;
#end
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArr = #[#"abcdef”,#"abcdef”,#"abcdef”,#"abcdef”,#"abcdef”];
self.tempCell = (CustomeCollectionViewCell*) [[[UINib nibWithNibName:#“CustomeCollectionViewCell" bundle:nil] instantiateWithOwner:self options:nil] firstObject];
[self.collectionView setContentInset:UIEdgeInsetsMake(8, 8, 8, 8)];
[self.collectionView registerNib:[UINib nibWithNibName:#"CustomeCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"CustomeCollectionViewCell"];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataArr.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CustomeCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CustomeCollectionViewCell" forIndexPath:indexPath];
cell.lblText.text = [self.dataArr objectAtIndex:indexPath.item];
cell.backgroundColor = [UIColor blackColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
self.tempCell.lblText.text = [self.dataArr objectAtIndex:indexPath.item];
return self.tempCell.intrinsicContentSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 8;
}

Try to add Dynamic Size of cell with following delegate method
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake((self.view.frame.size.width - 15)/2, (self.view.frame.size.width - 15)/2);
}

Related

UICollectionViewCell With automatic sizing not Working in iOS 9 But Working in iOS 10

I want to make dynamic size of UICollectionViewCell.
It's Working on iOS 10 but app is crash in iOS 9.
I have tried many solutions but none works.
Screen Shot of iPhone 5s (Working)
I Want the above output on iOS 9
- (void)viewDidLoad {
[super viewDidLoad];
[self.collectionView setContentInset:UIEdgeInsetsMake(8, 8, 8, 8)];
[self.collectionView registerNib:[UINib nibWithNibName:#"CustomeCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"CustomeCollectionViewCell"];
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
flowLayout.estimatedItemSize = CGSizeMake(1, 1);
flowLayout.minimumLineSpacing = 8.0f;
flowLayout.minimumInteritemSpacing = 8.0f;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataArr.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CustomeCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CustomeCollectionViewCell" forIndexPath:indexPath];
cell.lblText.text = [self.dataArr objectAtIndex:indexPath.item];
cell.backgroundColor = [UIColor blackColor];
return cell;
}
Error log
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array' *** First throw call stack: (0x2592791b 0x250c2e17 0x2583972b 0x2a6faba7 0x2a6b8adf 0x2a698753 0x2a698d87 0x29f08d57 0x29f06ed3 0x29f01fe9 0x29e9ea73 0x27f36bcd 0x27f32375 0x27f32209 0x27f316d1 0x27f313a5 0x29e95b79 0x258e96c9 0x258e79cd 0x258e7dff 0x25837229 0x25837015 0x26e27ac9 0x29f0b189 0x66f2d 0x254df873) libc++abi.dylib: terminating with uncaught exception of type NSException
My issue is solved in that some change in Code and implement some method that is available in given code.
1) implement intrinsicContentSize method in CustomeCollectionViewCell
2) set value of tempCell from that get size in sizeForItemAtIndexPath method
CustomeCollectionViewCell.m
- (CGSize)intrinsicContentSize
{
CGSize size = self.lblText.intrinsicContentSize;
size.width += 48; // add padding Width that Given in Cell
size.height += 32; // add padding Height
return size;
}
ViewController.m
#interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
#property (strong, nonatomic) CustomeCollectionViewCell *tempCell;
#property (strong, nonatomic) NSArray *dataArr;
#end
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArr = #[#"a",#"bc",#"def",#"ghijkl",#"mkopqrst",#"uvwxyz"];
self.tempCell = (CustomeCollectionViewCell*) [[[UINib nibWithNibName:#“CustomeCollectionViewCell" bundle:nil] instantiateWithOwner:self options:nil] firstObject];
[self.collectionView setContentInset:UIEdgeInsetsMake(8, 8, 8, 8)];
[self.collectionView registerNib:[UINib nibWithNibName:#"CustomeCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:#"CustomeCollectionViewCell"];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.dataArr.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CustomeCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CustomeCollectionViewCell" forIndexPath:indexPath];
cell.lblText.text = [self.dataArr objectAtIndex:indexPath.item];
cell.backgroundColor = [UIColor blackColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
self.tempCell.lblText.text = [self.dataArr objectAtIndex:indexPath.item];
return self.tempCell.intrinsicContentSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 8;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 8;
}

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 remove spacing between lines in UICollectionView programmatically?

I have a UICollectionView and I can't get 0 spacing between lines. I have added UICollectionViewDelegateFlowLayout in .h class and implemented
(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
and
(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger)section**
methods set them to return 0.0. Also in ViewDidLoad I dynamically created UICollectionViewFlowLayout and UICollectionView. For UICollectionViewFlowLayout I set minimumInteritemSpacing and minimumLineSpacing to 0 but space between lines is still more than 0.
This is my code:
- (void)initializeCollectionView {
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(50, 100);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[flowLayout setMinimumLineSpacing:0.0];
flowLayout.minimumInteritemSpacing = 0;
flowLayout.minimumLineSpacing = 0;
collView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 50, self.view.frame.size.width, self.view.frame.size.height-70) collectionViewLayout:flowLayout];
[collView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
[collView setBackgroundColor:[UIColor grayColor]];
collView.delegate = self;
collView.dataSource = self;
[[self view] addSubview:collView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 100;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0.0;
}
- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
Thank you for your answers.
I did it in a little different way. I created a collectionView programatically and added that to the view Controller. In my CollectionView Custom Class, I did all the customisation.
My Custom Collection View interface file-
#import <UIKit/UIKit.h>
#import "CustomCell.h"
#interface CustomCollectionView : UIView<UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate>
#property(nonatomic, strong) UICollectionView *myCollectionView;
#end
Now in the implementation File(CustomCollectionView.m), first I had to initialise and add my collectionView.
initWithFrame is called as soon as the view is drawn. So, I added my collectionView inside this view and let this view deal with all the delegate methods to customise my collection view and populate data through datasource methods.
-(id)initWithFrame:(CGRect)frame{
self=[super initWithFrame:frame];
if(self){
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
self.myCollectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 20, frame.size.width, frame.size.height) collectionViewLayout:flowLayout];
self.myCollectionView.backgroundColor=[UIColor whiteColor];
self.myCollectionView.delegate=self;
self.myCollectionView.dataSource=self;
[self.myCollectionView registerClass:[CustomCell class] forCellWithReuseIdentifier:#"customCell"];
[self addSubview:self.myCollectionView];
}
return self;
}
Now, let's implememt the UICollectionViewDelegateFlowLayout methods
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
//here I just made sure that I have square spaces boxes as my cell size
int width = self.myCollectionView.frame.size.width/5;
int height = width;
return CGSizeMake(width, height);
}
Now the UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 5;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 7;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CustomCell *cell =[collectionView dequeueReusableCellWithReuseIdentifier:#"customCell" forIndexPath:indexPath];
if(cell){
//customize the cell here
return cell;
}
}
Now when my custom view with collectionView is ready, I just added that to my viewController.
- (void)viewDidLoad {
[super viewDidLoad];
CustomCollectionView *myCollectionView = [[CustomCollectionView alloc]initWithFrame:CGRectMake(0, 10, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview: myCollectionView];
}
The above worked for me. You can do with storyboard to, but I found some complication when I tried to customise a collectionView connected by IBOutlet. So, I took this approach. There may be better ways to do that.

iOS: Scroll one cell at a time

I have horizontal scrolling set up now I would like for it to sort of scroll/snap one cell at a time when scrolling side to side.
Could someone shed some light? Here's the code I have so far:
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 1;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"MyCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
#pragma mark - UICollectionViewDelegateFlowLayout
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(50, 20, 50, 20);
}
[collectionView setPagingEnabled:YES]; might do the trick?
http://adoptioncurve.net/archives/2013/04/creating-a-paged-photo-gallery-with-a-uicollectionview/

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