I have a UICollectionView with 2 different types of UICollectionViewCells. There is a tab that prompts the showing of each type of cell and only one type of cell can be visible at a time.
For some reason, 1 type of cell aligns left in the UICollectionView, but the other cell horizontally aligns in the center. I'd like both types of cells to align left.
Edge insets are:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(10,10,10,10);
}
Any help would be much appreciated.
The cells will layout differently depending on their size, so you need to use different insets for each of your cell types. I think it should be doable like this:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:section];
if ([cell isKindOfClass:[MyClass1 class]]){
return UIEdgeInsetsMake(10,10,10,10);
}else{
return UIEdgeInsetsMake(20,10,10,10);
}
Substitute your correct class name for MyClass1 and experiment with the edge insets until you get the behavior you want.
Related
In my project i have collection ,in which horizontal pagination is enabled, Every thing working fine but, when i scroll,particular cell item not fit entire cell,It show half image of previous cell item and half current Items, i need One item to fit the entire screen ??? Any suggestion are welcome
Here is the code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath; {
SingleItemCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"SingleItemCollectionViewCell" forIndexPath:indexPath];
[cell ConfigaureCollectionViewItem:self.totalCellItems[indexPath.row]]; return cell;
}
-(CGSize)collectionView:(UICollectionView )collectionView layout:(UICollectionViewLayout)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize size = CGSizeMake(self.bounds.size.width - 20, self.bounds.size.height - 40);
return size;
}
Perhaps you should be using UIPageViewController in stead of UICollectionView. From your question it seems that you are trying to mimic the behaviour of the former.
I'm trying to setup what should be a simple horizontal layout using UICollectionView, going around in circles without achieving the desired result so any pointer or examples would be gratefully appreciated.
Probably little point in me pasting code as changed so often without success.
The image shows two rows, the first is a single item and is the correct size and aligned correctly in the centre. The second row has 3 items, the first should be the same size as the item above, with the next item edge being just visible indicating another item. When the item is swiped to the left their should be 3 items visible — the main item fully visible in the centre and items 1 & 3 just visible at the left and right edges.
I have tried setting paging on, changing insetForSectionAtIndex, minimumLineSpacingForSectionAtIndex, minimumInteritemSpacingForSectionAtIndex.
Edit - 16th December
I haven't explained or illustrated this very well, so have better illustrated below. I know how to create the collection view, set the item size etc but can not get the desired layout.
This is a single row horizontal UICollectionView with one item always in full view and its neighbouring items in partial view indicating to the user there are more items to the left or right depending on the scroll position and item count.
when Item 1 is in full view, item 2 is in partial view
when Item 2 is in full view, item 1 and 3 are in partial view (left and right)
when Item 3 is in full view, item 2 is in partial view (left)
Ok, I've done this as follows;
sticking with an item size of 288x180 for my case
1/. Set the item size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(288, 180);
}
2/. Set insetForSectionAtIndex
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
//top, left, bottom, right
return UIEdgeInsetsMake(0, 16, 0, 16);
}
3/. Set minimumInteritemSpacingForSectionAtIndex to ensure spacing
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 5;
}
4/. When creating the cell id did the following;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell* cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath];
if (!cell)
{
cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath];
cell.contentView.width = 288;
cell.contentView.backgroundColor = [UIColor whiteColor];
}
return cell;
}
5/. To achieve the paging effect correctly ensure collectionView.paging = NO and subclass UICollectionViewFlowLayout to use targetContentOffsetForProposedContentOffset for correctly setting the scrollview offset
Not sure if this is the best way but it has given me the desired result..
Create a collection view and set the height according to the height of the items in YOUR SECOND ROW and then set the scroll direction to Horizontal. Also
Here is an image attached, check the settings of the collection view accordingly.
The following method will set the cell width according to your second row. The first cell would be displayed in 3/4th of the screen and second cell 1/4th part.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake( (self.view.frame.size.width / 4) * 3, "YOUR SECOND ROW ITEM HEIGHT");
}
I have done this for 5 cells on the screen
Attaching the code below.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake( self.view.frame.size.width / 5, 70);
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row > pos)
{
if (indexPath.row - pos == 2) {
pos = pos + 1;
}
[self changeDate];
}
else if (indexPath.row == pos)
{
NSLog(#"Do Nothing");
}
else
{
if (indexPath.row + 2 == pos) {
pos = pos - 1;
}
[self changeDate1];
}
//NSLog(#"%#",[arrDate objectAtIndex:indexPath.row]);
}
-(void)changeDate
{
if (pos<(arrDate.count - 2)) {
pos=pos+1;
[self.tpCollectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:pos inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
NSLog(#"%#",[arrDate objectAtIndex:pos]);
self.lblMovieName.text =[arrDate objectAtIndex:pos];
}
}
-(void)changeDate1
{
if(pos>2)
{
pos=pos-1;
[self.tpCollectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:pos inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
NSLog(#"%#",[arrDate objectAtIndex:pos]);
self.lblMovieName.text =[arrDate objectAtIndex:pos];
}
else{
}
}
I'm trying to display pictures in a collection view, 1 picture at a time and allow them to be scrolled horizontally.
so i was hoping to have the cell fit the size of the collection view, perhaps with a bit of margin.
I've tried to do it by setting the cell frame to the same as the collection view's frame
CGRect containerFrame = self.photoCollectionView.frame;
cell.frame = CGRectMake(containerFrame.origin.x, containerFrame.origin.y, containerFrame.size.width, containerFrame.size.height);
but the cell just disappears all together.
Is there a standard way to do it?
Take a look at the UICollectionViewFlowLayout Class Reference. You should use UICollectionViewDelegateFlowLayout.
Implement this method to change the size of cells
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
and to change the spacing between cells
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
How can I set the collection cell view to dynamically stretch to iphone screen width (e.g. iphone 5s, iphone 6 plus)?
I tried:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
(ResultCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellClass
forIndexPath:indexPath];
cell.bounds = CGRectMake(0,0, self.view.bounds.size.width, 150);
return cell;
}
That does not work. I don't see the content get stretch to the right side of the screen.
I have tried adding this delegate method:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGSize cellSize;
cellSize.width = self.view.bounds.size.width;
// body view height
cellSize.height = 150;
return cellSize;
}
I have set breakpoints in the method, but that method never get called?
I had the same issue with the same use case. I finally ended up doing
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(collectionView.bounds.size.width, 150);
}
This changes the size of each item (cell) of the collection view. Hence you could change the size of each cell using this. Here i need the cell width to be same as of my UICollectionView so i passed the UICollectionview's width and specific height that i desired. Hope this would help.
Also there is no need to set the cell bounds in - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath as the size gets set via - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
Also make sure that you have attached the desired Delegates & DataSources to the UICollectionView
The size of the cells are specified by the layout object of the collection view. Are you using a UICollectionViewFlowLayout? Try either setting the itemSize property of the layout object or implementing the delegate method: collectionView:layout:sizeForItemAtIndexPath:
You will be able to specify the size of the item (cell) relative to the collection view's bounds there.
Keep in mind that your collection view also needs to be set up so that it resizes with your view controller. If you're using a UICollectionViewController that should be set up automatically. Otherwise, you'll have to constrain your collection view to the bounds of its superview.
Update:
You can set the itemSize property of the layout directly on the layout:
self.layout.itemSize = CGSizeMake(CGRectGetWidth(self.collectionView.bounds), 100);
or, (better if you're handling rotation or resizing), implement the appropriate delegate call back:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(CGRectGetWidth(collectionView.bounds), 100);
}
I'd recommend reading the appropriate UICollectionView docs to get more familiar with how collection views and their layout's work:
UICollectionViewDelegateFlowLayout
UICollectionViewFlowLayout
UICollectionView Programming Guide
http://postimg.org/image/6bws3catp/
As you can see on the image I need something that gives me the possibility of resizing a cell depending on the length of the text that contains.
I' ve been trying to do that with a UICollectionview but the cells have always the same size and if I try to alterate the size playing with the frame.size and location parameters the scroll gets crazy.
Maybe the UICollectionView isn't the best choice...
Thank you very much
EDIT:
Because of your answers my cells are able to change dynamically their size but the margins aren't behaving as I expected.
The margins of the cells depends always on the biggest cell of the same row
http://postimg.org/image/3scthf9rv/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
return 6;
}
I have implement this to set my margin value between cells in 6 points, but maybe this only works when you have one cell in each row in a vertical collection view..
Thank you again for all your help
You can check out https://github.com/bryceredd/RFQuiltLayout . Looks
like something you can use for this...
you can override the following method and return a CGSize object that specifies the size you want to use for each cell. Using this method, you can actually have each cell be a different size:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
Example:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(100, 100);
}
Your view controller needs to be a delegate of UICollectionViewDelegateFlowLayout in order for this method to be called. So don't forget to add that delegate declaration to your view controller's .h file, such as:
#interface MyViewController () <UICollectionViewDelegateFlowLayout>
UICollectionView is the correct choice. You just need to customise the flow layout attributes.
Read Customizing the Flow Layout Attributes
Specifically you would need to implement Collection View Delegate method:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
// In this method you can calculate the size of the string for each cell
UIFont *font = // font to create the text for each cell
NSString *string = // text string for each cell
CGSize size = [string sizeWithFont];
return size;
}