ios - 如何在 UICollectionView 中居中对齐项目?

标签 ios uicollectionview

我有一个 CollectionView,它显示了一些启用了水平滚动和分页的图像。第一页和最后一页显示完美,但其余页面显示不正确,它们显示相邻页面的部分图像,因此它们未正确对齐(附上屏幕截图)。如何让所有页面看起来都一样,即图像正确居中对齐,这样相邻的页面就不会被偷看。

请注意第 2 页中从左侧窥视的图像,因此实际图像从左侧被剪裁。我该如何解决这个问题,使所有页面看起来都像第 1 页。

最佳答案

如您在评论中的回复,可以找到答案here .这是您要求的 Swift 解决方案。

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;
}

关于ios - 如何在 UICollectionView 中居中对齐项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32391125/

相关文章:

xcode - 为什么 viewDidLoad 在 didSelectItemAtIndexPath 之前运行?

ios - 新的 PhoneGap/Cordova iOS 项目重命名后无法运行

iphone - 如何在 iphone 中通过触摸移动重新绘制已删除的图像

ios - 无需登录即可从 Instagram 帐户获取公开照片

ios - Swift 4 添加和删除索引 : 0 with animation 处的自定义单元格

ios - 如何在 Collection View 中给 UILabel 一个闪烁的效果

ios - Xcode 错误 ITMS 90096 - 我没有使用任何启动屏幕

ios - 当单元格可见时在轮播中播放视频

ios - Swift - UICollectionView 在一行中显示多个项目

ios - Swift CollectionView 自定义布局单元格间距