How to Expand Uicollectionview Contentsize When Paging Enable

How to expand UICollectionView contentSize when paging enable?

You need to subclass UICollectionViewLayout and override the collectionViewContentSize method. I subclassed UICollectionViewFlowLayout so I wouldn't have to re-write all the layout code.

I'm building a 4x4 grid, so my method looks like this:

- (CGSize)collectionViewContentSize
{
NSInteger itemCount = [self.collectionView numberOfItemsInSection:0];
NSInteger pages = ceil(itemCount / 16.0);

return CGSizeMake(320 * pages, self.collectionView.frame.size.height);
}

Side note, when you use a custom layout, you lose the ability to set the some of the display properties in the Interface Builder. You can set them programatically in the init method of your custom UICollectionViewLayout subclass. Here's mine for reference:

- (id)init
{
self = [super init];
if (self) {
[self setup];
}

return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
[self setup];
}

return self;
}

- (void)setup
{
self.itemSize = CGSizeMake(65.0f, 65.0f);
self.minimumLineSpacing = 15;
self.sectionInset = UIEdgeInsetsMake(7.5f, 7.5f, 30.0f, 7.5f);
[self setScrollDirection:UICollectionViewScrollDirectionHorizontal];
}

How to adjust height of UICollectionView to be the height of the content size of the UICollectionView?

I would suggest the following:

  1. Add a height constraint to your collection view.
  2. Set its priority to 999.
  3. Set its constant to any value that makes it reasonably visible on the storyboard.
  4. Change the bottom equal constraint of the collection view to greater or equal.
  5. Connect the height constraint to an outlet.
  6. Every time you reload the data on the collection view do the following:

You may also want to consider the Inset of the collection view by adding it to the content size.

Code Sample:

CGFloat height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
heightConstraint.constant = height
self.view.setNeedsLayout() Or self.view.layoutIfNeeded()

Explanation: Extra, You don't have to read if you understand it. obviously!!

The UI will try to reflect all the constraints no matter what are their priorities. Since there is a height constraint with lower priority of (999), and a bottom constraint of type greater or equal. whenever, the height constraint constant is set to a value less than the parent view height the collection view will be equal to the given height, achieving both constraints.

But, when the height constraint constant set to a value more than the parent view height both constraints can't be achieved. Therefore, only the constraint with the higher priority will be achieved which is the greater or equal bottom constraint.

The following is just a guess from an experience. So, it achieves one constrant. But, it also tries to make the error in the resulted UI for the other un-achieved lower priority constraint as lowest as possible. Therefore, the collection view height will be equal to the parent view size.

Paging UICollectionView by cells, not screen

OK, so I found the solution here: targetContentOffsetForProposedContentOffset:withScrollingVelocity without subclassing UICollectionViewFlowLayout

I should have searched for targetContentOffsetForProposedContentOffset in the begining.

UICollectionView Horizontal Paging not centered

Remove spaces between items. For horizontal scrolling collection view set minimum line spacing to 0. You can do this with interface builder or with method of UICollectionViewDelegateFlowLayout protocol:

- (CGFloat)collectionView:(UICollectionView *)collectionView 
layout:(UICollectionViewLayout *)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0;
}

Sample Image

Another way is making your cell's width less than collectionView's width for a value of horizontal space between items. Then add section insets with left and right insets that equal a half of horizontal space between items. For example, your minimum line spacing is 10:

- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 10;
}

- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(collectionView.frame.size.width - 10, collectionView.frame.size.height);
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 5, 0, 5);
}

Sample Image

And third way: manipulate collectionView scroll in scrollViewDidEndDecelerating: method:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == self.collectionView) {
CGPoint currentCellOffset = self.collectionView.contentOffset;
currentCellOffset.x += self.collectionView.frame.size.width / 2;
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:currentCellOffset];
[self.collectionView scrollToItemAtIndexPath:indexPath
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:YES];
}
}

Sample Image

Paging in Collection View not centering properly

You have to make sure that your section inset + line spacing + cell width all equals exactly the bounds of the CollectionView. I use the following method on a custom UICollectionViewFlowLayout sublcass:

- (void)adjustSpacingForBounds:(CGRect)newBounds {
NSInteger count = newBounds.size.width / self.itemSize.width - 1;

CGFloat spacing = (newBounds.size.width - (self.itemSize.width * count)) / count;

self.minimumLineSpacing = spacing;

UIEdgeInsets insets = self.sectionInset;
insets.left = spacing/2.0f;
self.sectionInset = insets;
}

You have to remember that UICollectionView is just a sublcass of UIScrollView so it doesn't know how you want your pagination to work. Before UICollectionView you would have to handle all of this math when laying out your subviews of the UIScrollView.

How to implement clean paging of collectionview where it scrolls to full page

When you get the Collection that would be displayed in your CollectionView you should do a modulo on it by 9 to get the remainder. If the modulo is 0, do nothing. If the modulo is any other number, subtract that number from 9 and add that many "dummy" cells to your collection to fill them out.

Here is some code to get you started:

int remainder = (int)[self.collectionView numberOfItemsInSection:0] % 9;  //I am assuming you don't have more than one section
if(remainder){
for(i = 9; i > remainder; i--){
//add a dummy item to collectionView
}
}

UICollectionView scroll issue with paging enabled after tap

If you want to current page than you should get you page from scrollview as this

 func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

let pageNumber = round(scrollView.contentOffset.x / collectionCustom.frame.width) // You can change width according you
pageControl.currentPage = Int(pageNumber)

}


Related Topics



Leave a reply



Submit