以相反的顺序填充UICollectionView

Mug*_*diq 7 iphone ios uicollectionview uicollectionviewcell

我想以相反的顺序填充UICollectionView,以便UICollectionView的最后一项首先填充,然后填充第二项,依此类推.实际上我正在应用动画,项目逐一出现.因此,我希望最后一项显示出来.

Tou*_*hid 9

斯威夫特 4.2

我找到了一个简单的解决方案,并为我工作以首先显示集合视图的最后一项:

内部 viewDidLoad() 方法:

collectionView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(Double.pi)))
Run Code Online (Sandbox Code Playgroud)

并在返回单元格之前在 collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) 方法中:

cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
Run Code Online (Sandbox Code Playgroud)

(可选)下面的行是自动滚动和平滑滚动显示新项目所必需的。

加载新数据后添加以下行:

   if self.dataCollection.count > 0 {
      self.collectionView.scrollToItem(at: //scroll collection view to indexpath
      NSIndexPath.init(row:(self.collectionView?.numberOfItems(inSection: 0))!-1, //get last item of self collectionview (number of items -1)
      section: 0) as IndexPath //scroll to bottom of current section
      , at: UICollectionView.ScrollPosition.bottom, //right, left, top, bottom, centeredHorizontally, centeredVertically
      animated: true)
   }
Run Code Online (Sandbox Code Playgroud)

  • 很有创意!! (2认同)

jly*_*ith 5

我感到惊讶的是,苹果公司使人们害怕不在文档中编写自己的UICollectionViewLayout。这真的非常简单。这是我刚刚在应用程序中使用的实现,该实现将完全执行要求的操作。新项目将显示在底部,而当没有足够的内容填满屏幕时,这些项目将在底部对齐,就像您在消息应用程序中看到的那样。换句话说,数据源中的零项是堆栈中的最低项。

此代码假定您有多个部分,每个部分具有固定高度的项目,项目之间没有空格,并且集合视图的整个宽度。如果您的布局更复杂,例如节和项之间的间距不同,或者可变高度的项,Apple的意图是您使用prepare()回调来执行繁重的工作和缓存大小信息,以备后用。

此代码使用Swift 3.0。

//
//  Created by John Lyon-Smith on 1/7/17.
//  Copyright © 2017 John Lyon-Smith. All rights reserved.
//

import Foundation
import UIKit

class InvertedStackLayout: UICollectionViewLayout {
    let cellHeight: CGFloat = 100.00 // Your cell height here...

    override func prepare() {
        super.prepare()
    }

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var layoutAttrs = [UICollectionViewLayoutAttributes]()

        if let collectionView = self.collectionView {
            for section in 0 ..< collectionView.numberOfSections {
                if let numberOfSectionItems = numberOfItemsInSection(section) {
                    for item in 0 ..< numberOfSectionItems {
                        let indexPath = IndexPath(item: item, section: section)
                        let layoutAttr = layoutAttributesForItem(at: indexPath)

                        if let layoutAttr = layoutAttr, layoutAttr.frame.intersects(rect) {
                            layoutAttrs.append(layoutAttr)
                        }
                    }
                }
            }
        }

        return layoutAttrs
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        let layoutAttr = UICollectionViewLayoutAttributes(forCellWith: indexPath)
        let contentSize = self.collectionViewContentSize

        layoutAttr.frame = CGRect(
            x: 0, y: contentSize.height - CGFloat(indexPath.item + 1) * cellHeight,
            width: contentSize.width, height: cellHeight)

        return layoutAttr
    }

    func numberOfItemsInSection(_ section: Int) -> Int? {
        if let collectionView = self.collectionView,
            let numSectionItems = collectionView.dataSource?.collectionView(collectionView, numberOfItemsInSection: section)
        {
            return numSectionItems
        }

        return 0
    }

    override var collectionViewContentSize: CGSize {
        get {
            var height: CGFloat = 0.0
            var bounds = CGRect.zero

            if let collectionView = self.collectionView {
                for section in 0 ..< collectionView.numberOfSections {
                    if let numItems = numberOfItemsInSection(section) {
                        height += CGFloat(numItems) * cellHeight
                    }
                }

                bounds = collectionView.bounds
            }

            return CGSize(width: bounds.width, height: max(height, bounds.height))
        }
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        if let oldBounds = self.collectionView?.bounds,
            oldBounds.width != newBounds.width || oldBounds.height != newBounds.height
        {
            return true
        }

        return false
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

只需单击情节提要中的 UICollectionView,在视图部分下的检查器菜单中将语义更改为强制从右到左

我附上了一张图片来展示如何在检查器菜单中执行此操作:

检查器中从右到左的图像


Pau*_*uls 3

我假设您正在使用 UICollectionViewFlawLayout,并且这没有逻辑可以做到这一点,它只能按从上到左下到右的顺序工作。为此,您必须构建自己的布局,您可以创建一个继承自 UICollectionViewLayout 的新对象。

看起来工作量很大,但实际上并没有那么多,你必须实现 4 个方法,而且由于你的布局是自下而上的,所以应该很容易知道每个单元格的框架。

在此处查看苹果教程:https://developer.apple.com/library/prerelease/ios/documentation/WindowsViews/Conceptual/CollectionViewPGforIOS/CreatingCustomLayouts/CreatingCustomLayouts.html