菜鸟教程小白 发表于 2022-12-13 10:23:08

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


                                            <p><p>我有一个 CollectionView 显示许多启用了水平滚动和分页的图像。第一页和最后一页显示完美,但其余页面未正确显示,它们显示相邻页面的部分图像,因此它们未正确对齐(附上截图)。如何使所有页面看起来相同,即图像正确居中对齐,以便相邻页面不会偷看。</p>

<p> <img src="/image/dfp7m.png" width="300"/>
<img src="/image/Jrqtb.png" width="300"/> </p>

<p>请注意第 2 页中的图像从左侧窥视,因为实际图像从左侧被剪切。我该如何解决这个问题,使所有页面看起来像第 1 页。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>正如您在评论中回复的那样,可以找到答案<a href="https://stackoverflow.com/questions/13228600/uicollectionview-align-logic-missing-in-horizontal-paging-scrollview" rel="noreferrer noopener nofollow">here</a> .这是您要求的 Swift 解决方案。</p>

<p><strong>Swift 1.2</strong> </p>

<pre><code>override func collectionViewContentSize() -&gt; 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!) -&gt; 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 &gt; 1 ? (columnCount - 1) * minimumLineSpacing : 0)) / 2.0
    let pageMarginY = (canvasSize.height - rowCount * itemSize.height - (rowCount &gt; 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) -&gt; UICollectionViewLayoutAttributes! {
    var attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
    attributes.frame = frameForItemAtIndexPath(indexPath)
    return attributes
}

override func layoutAttributesForElementsInRect(rect: CGRect) -&gt; ? {
    let superAttrs = super.layoutAttributesForElementsInRect(rect)
    if let originAttrs = superAttrs as? {
      var attrs = ()

      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;
}
</code></pre>

<p><strong>Swift 2.0</strong></p>

<pre><code>override func collectionViewContentSize() -&gt; 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!) -&gt; 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 &gt; 1 ? (columnCount - 1) * minimumLineSpacing : 0)) / 2.0
    let pageMarginY = (canvasSize.height - rowCount * itemSize.height - (rowCount &gt; 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) -&gt; UICollectionViewLayoutAttributes? {
    let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
    attributes!.frame = frameForItemAtIndexPath(indexPath)
    return attributes
}

override func layoutAttributesForElementsInRect(rect: CGRect) -&gt; ? {
    let superAttrs = super.layoutAttributesForElementsInRect(rect)
    if let originAttrs = superAttrs as ! {
      var attrs = ()

      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;
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何在 UICollectionView 中居中对齐项目?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/32391125/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/32391125/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何在 UICollectionView 中居中对齐项目?