Reputation: 81
I have a CollectionView showing a number of images with horizontal scroll and paging enabled. The first and the last pages are showing perfectly but rest of the pages are not showing properly, they are showing parts of images from the adjacent page due to which they are not aligned properly (screenshots attached). How do I make all pages look same i.e. the images properly center aligned so that adjacent pages don't peek.
Notice the image peeking in Page 2 from the left side due to which the actual image on is getting clipped from the left. How can I fix this so that all pages look like page 1.
Upvotes: 2
Views: 1834
Reputation: 700
As you have replied in the comment, answer can be found here. Here is the Swift solution you have asked for.
Swift 1.2
override func collectionViewContentSize() -> CGSize {
// Only support single section for now.
// Only support Horizontal scroll
let count = collectionView!.dataSource!.collectionView(collectionView!, numberOfItemsInSection: 0)
let canvasSize = collectionView!.frame.size
var contentSize = canvasSize
if (scrollDirection == .Horizontal) {
let rowCount = (canvasSize.height - itemSize.height) / (itemSize.height + minimumInteritemSpacing) + 1
let columnCount = (canvasSize.width - itemSize.width) / (itemSize.width + minimumLineSpacing) + 1;
let page = ceil(CGFloat(count) / (CGFloat)(rowCount * columnCount));
contentSize.width = page * canvasSize.width;
}
return contentSize;
}
func frameForItemAtIndexPath(indexPath: NSIndexPath!) -> CGRect {
let canvasSize = collectionView!.frame.size
let rowCount = (canvasSize.height - itemSize.height) / (itemSize.height + minimumInteritemSpacing) + 1
let columnCount = (canvasSize.width - itemSize.width) / (itemSize.width + minimumLineSpacing) + 1
let pageMarginX = (canvasSize.width - columnCount * itemSize.width - (columnCount > 1 ? (columnCount - 1) * minimumLineSpacing : 0)) / 2.0
let pageMarginY = (canvasSize.height - rowCount * itemSize.height - (rowCount > 1 ? (rowCount - 1) * minimumInteritemSpacing : 0)) / 2.0
let page = CGFloat(indexPath.row) / (rowCount * columnCount)
let remainder = CGFloat(indexPath.row) - page * (rowCount * columnCount)
let row = remainder / columnCount
let column = remainder - row * columnCount
var cellFrame = CGRect.zeroRect
cellFrame.origin.x = pageMarginX + column * (itemSize.width + minimumLineSpacing);
cellFrame.origin.y = pageMarginY + row * (itemSize.height + minimumInteritemSpacing);
cellFrame.size.width = itemSize.width;
cellFrame.size.height = itemSize.height;
if (scrollDirection == .Horizontal) {
cellFrame.origin.x += page * canvasSize.width;
}
return cellFrame;
}
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
var attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
attributes.frame = frameForItemAtIndexPath(indexPath)
return attributes
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
let superAttrs = super.layoutAttributesForElementsInRect(rect)
if let originAttrs = superAttrs as? [UICollectionViewLayoutAttributes] {
var attrs = [UICollectionViewLayoutAttributes]()
for (index, var attr) in enumerate(originAttrs) {
let indexPath = attr.indexPath
let itemFrame = frameForItemAtIndexPath(indexPath)
if CGRectIntersectsRect(itemFrame, rect) {
attr = layoutAttributesForItemAtIndexPath(indexPath)
attrs.append(attr)
}
}
return attrs
}
return superAttrs;
}
Swift 2.0
override func collectionViewContentSize() -> CGSize {
// Only support single section for now.
// Only support Horizontal scroll
let count = collectionView!.dataSource!.collectionView(collectionView!, numberOfItemsInSection: 0)
let canvasSize = collectionView!.frame.size
var contentSize = canvasSize
if (scrollDirection == .Horizontal) {
let rowCount = (canvasSize.height - itemSize.height) / (itemSize.height + minimumInteritemSpacing) + 1
let columnCount = (canvasSize.width - itemSize.width) / (itemSize.width + minimumLineSpacing) + 1;
let page = ceil(CGFloat(count) / (CGFloat)(rowCount * columnCount));
contentSize.width = page * canvasSize.width;
}
return contentSize;
}
func frameForItemAtIndexPath(indexPath: NSIndexPath!) -> CGRect {
let canvasSize = collectionView!.frame.size
let rowCount = (canvasSize.height - itemSize.height) / (itemSize.height + minimumInteritemSpacing) + 1
let columnCount = (canvasSize.width - itemSize.width) / (itemSize.width + minimumLineSpacing) + 1
let pageMarginX = (canvasSize.width - columnCount * itemSize.width - (columnCount > 1 ? (columnCount - 1) * minimumLineSpacing : 0)) / 2.0
let pageMarginY = (canvasSize.height - rowCount * itemSize.height - (rowCount > 1 ? (rowCount - 1) * minimumInteritemSpacing : 0)) / 2.0
let page = CGFloat(indexPath.row) / (rowCount * columnCount)
let remainder = CGFloat(indexPath.row) - page * (rowCount * columnCount)
let row = remainder / columnCount
let column = remainder - row * columnCount
var cellFrame = CGRect.zeroRect
cellFrame.origin.x = pageMarginX + column * (itemSize.width + minimumLineSpacing);
cellFrame.origin.y = pageMarginY + row * (itemSize.height + minimumInteritemSpacing);
cellFrame.size.width = itemSize.width;
cellFrame.size.height = itemSize.height;
if (scrollDirection == .Horizontal) {
cellFrame.origin.x += page * canvasSize.width;
}
return cellFrame;
}
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
attributes!.frame = frameForItemAtIndexPath(indexPath)
return attributes
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let superAttrs = super.layoutAttributesForElementsInRect(rect)
if let originAttrs = superAttrs as [UICollectionViewLayoutAttributes]! {
var attrs = [UICollectionViewLayoutAttributes]()
for (_, var attr) in originAttrs.enumerate() {
let indexPath = attr.indexPath
let itemFrame = frameForItemAtIndexPath(indexPath)
if CGRectIntersectsRect(itemFrame, rect) {
attr = layoutAttributesForItemAtIndexPath(indexPath)!
attrs.append(attr)
}
}
return attrs
}
return superAttrs;
}
Upvotes: 1