我希望能够倒序填充UICollectionView,这样UICollectionView的最后一个项目将首先填满,然后是倒数第二个项目,以此类推。实际上,我正在应用动画,项目逐个显示出来。因此,我希望最后一个项目首先显示出来。
我希望能够倒序填充UICollectionView,这样UICollectionView的最后一个项目将首先填满,然后是倒数第二个项目,以此类推。实际上,我正在应用动画,项目逐个显示出来。因此,我希望最后一个项目首先显示出来。
Swift 4.2
我发现了一种简单的解决方案,可以让集合视图中的最后一个项目显示在第一位:
在viewDidLoad()方法中:
collectionView.transform = CGAffineTransform.init(rotationAngle: (-(CGFloat)(Double.pi)))
cell.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
(可选)以下几行将自动滚动并平滑显示新项目。
在加载新数据后添加以下几行:
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)
}
//
// 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
}
}
只需在Storyboard中单击UICollectionView,在视图部分的检查器菜单下更改语义为强制从右到左
我附上一张图片,展示如何在检查器菜单中进行操作:
数据收集实际上不需要修改,但这样做可以产生预期的结果。因为您控制以下方法:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
只需返回从所请求的索引中反转创建的单元格即可。索引路径是单元格在集合中的索引,不一定是源数据集中的索引。我用这个方法来实现从CoreData集合中进行反向显示。
let desiredIndex = dataProfile!.itemEntries!.count - indexPath[1] - 1;
这里有一个简单的可行解决方案!
// Change the collection view layer transform.
collectionView.transform3D = CATransform3DMakeScale(1, -1, 1)
// Change the cell layer transform.
cell.transform3D = CATransform3DMakeScale(1, -1, 1)
不知道这个还有没有用,但我想对其他人来说可能会非常有用。
如果你的集合视图单元格高度相同,那么实际上有一个比构建自定义UICollectionViewLayout更简单的解决方案。
首先,只需创建一个集合视图顶部约束的输出口,并将此代码添加到视图控制器中:
-(void)viewWillAppear:(BOOL)animated {
[self.view layoutIfNeeded]; //for letting the compiler know the actual height and width of your collection view before we start to operate with it
if (self.collectionView.frame.size.height > self.collectionView.collectionViewLayout.collectionViewContentSize.height) {
self.collectionViewTopConstraint.constant = self.collectionView.frame.size.height - self.collectionView.collectionViewLayout.collectionViewContentSize.height;
}
这很简单:
yourCollectionView.inverted = true
PS : Texture/IGListKit也是一样的。