Horizontal paging UICollectionView with automatic item size in a vertical stack view?
Since CollectionViews (and TableViews) don't have an intrinsicContentSize
, there is no way for the layout engine to know the correct size of your collection without the appropriate constraints. A subclass is needed to provide this property.
In your subclass:
override var intrinsicContentSize: CGSize {
return CGSize(self.contentSize.height, self.superview!.bounds.width)
}
Also, don't forget to invalidate your content size when reloading data:
override func reloadData() {
super.reloadData()
self.invalidateIntrinsicContentSize()
}
For a more detailed explanation on intrinsicContentSize check Apple's Documentation
UICollectionView horizontal paging with space between pages
Solution one:
collectionView.isPagingEnabled = false
- add a
minimumLineSpacing
for the distance between pages - implement
targetContentOffsetForProposedContentOffset:withScrollingVelocity:
to move the contentOffset to the closest page. You can calculate the page with simple math based on youritemSize
andminimumLineSpacing
, but it can take a little work to get it right.
Solution Two:
collectionView.isPagingEnabled = true
- add a
minimumLineSpacing
for the distance between pages - the paging size is based on the bounds of the collectionView. So make the collectionView larger then then screenSize. For example, if you have a
minimumLineSpacing
of 10 then set the frame of the collectionView to be {0,-5, width+10, height} - set a contentInset equal to the
minimumLineSpacing
to make the first and last item appear correctly.
UICollectionView - vertical scrollling, horizontal paging with custom layout
I believe if the collection view item widths are less than or equal to the width of the collection view, then the horizontal paging should work via the pagingEnabled
property. Otherwise, you need to create the paging effect yourself using the UIScrollView
delegate methods and animating to offsets yourself after a certain threshold
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;
}
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);
}
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];
}
}
UICollectionView custom horizontal paging layout
it depends on 3 factors
1) Section Insets
2) Cell Spacing
3) Cell Size
Any change in each you have to change others
for your case
1) Set left & right with 20
2) set cell spacing to 10
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 10
}
func collectionView(collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 10
}
3) Set cell size
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width / 1.15 ,height: collectionView.frame.height)
}
4) this will center cell in screen
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let pageWidth:CGFloat = scrollView.frame.width / 1.15 + cellSpacing ;
let currentOffset:CGFloat = scrollView.contentOffset.x;
let targetOffset:CGFloat = targetContentOffset.memory.x
var newTargetOffset:CGFloat = 0;
if targetOffset > currentOffset
{
newTargetOffset = ceil(currentOffset / pageWidth) * pageWidth;
}
else
{
newTargetOffset = floor(currentOffset / pageWidth) * pageWidth;
}
if newTargetOffset < 0
{
newTargetOffset = 0
}
else if newTargetOffset > scrollView.contentSize.width
{
newTargetOffset = scrollView.contentSize.width;
}
targetContentOffset.memory.x = currentOffset
scrollView.setContentOffset(CGPointMake(newTargetOffset, 0), animated: true)
}
Related Topics
Countdown with Several Decimal Slots, Using Nstimer in Swift
Ios: How to Create Expandable Tableview in Swift Without Using Third Party Libraries or Pods
What Is the Simplest Way to Retrieve the Device Serial Number of an iOS Device Using Monotouch
iOS Swift Avplayer Inside Uiview How to Make It Work
iOS How to Restart App for Changing Language Swift 4
How to Set the Collection View Cell Size Exactly Equal to the Collection View in iOS
Error When Trying to Save a Captured Image in Swift
Cannot Invoke 'Decode' with an Argument List of Type '(T, From: Data)'
Didoutputsamplebuffer Delegate Not Called
iOS Sound Not Playing in Swift
Can't Copy File from Bundle to Documents Directory in iOS
Changing Constraint When Keyboard Appears - Swift
Swift - Nsdate and Last Week of Year
Swift:'(Nsobject, Anyobject)' Does Not Have a Member Named 'Subscript'