我试图理解为什么Collection View保持居中对齐集合中的最后一个单元格 我创建了一个简单的基于Flow布局的集合视图。我正在使用Autolayout标志 - 我不确定是否会导致此问题。
每当我从Collection视图中删除一个单元格时 - 前几个似乎工作正常并向左滚动。然而,当我移除倒数第二个时,突然最后一个单元从左对齐变为中心对齐。 有人有解释吗?这看起来很奇怪。
如何制作它以使所有单元格向左滚动并保持与左对齐。
编辑:这是视图层次调试: http://imgur.com/a/NxidO
以下是行为
我制作了一个简单的github来演示它:https://github.com/grantkemp/CollectionViewIssue
这是代码:
var dataforCV = ["short","longer phrase", "Super long Phrase"]
override func viewDidLoad() {
super.viewDidLoad()
demoCollectionView.reloadData()
let layout = UICollectionViewFlowLayout()
// Bug Description - > UICollectionViewFlowLayoutAutomaticSize will center Align the layout if it has only a single cell - but it will left align the content if there is more than one cell.
// I would expect this behaviour to be consistently left aligning the content.
//How to repeat: If you comment out UICollectionViewFlowLayoutAutomaticSize then the collection view will show 3 cells being left aligned and it will continue to left align all the content no matter how many cells you remove.
// But: if you leave turn UICollectionViewFlowLayoutAutomaticSize on - then it will intially show 3 cells being left aligned, and then as you click to remove each cell they will stay left aligned until the last single cell will suddenly center align in the collection view
// see here for the screen recording:https://i.stack.imgur.com/bledY.gif
// see here for the view hierachy debuggins screen: http://imgur.com/a/NxidO
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
// <-- End Bug Description
demoCollectionView.collectionViewLayout = layout
}
//MARk: CollectionView
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? collectionCell
cell?.text.text = dataforCV[indexPath.row]
return cell!
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataforCV.count
}
//Remove the item from the array if selected
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
dataforCV.remove(at: indexPath.row)
demoCollectionView.deleteItems(at: [indexPath])
}
答案 0 :(得分:7)
我设法使用以下两个步骤解决了这个问题: 1.记录了一个关于使用UICollectionViewFlowLayoutAutomaticSize时我注意到有关细胞行为变化的奇怪行为的Apple的错误 2.我通过创建一个修改过的CustomViewFlowLayout做了一个工作(找不到原始的SO / github问题,我看到这个方法使用了 - 如果我找到的话我会添加它)然后我添加了UICollectionViewFlowLayoutAutomaticSize设置 - 并且它工作得很漂亮。
示例代码:
class MyLeftCustomFlowLayout:UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
var leftMargin = sectionInset.left
var maxY: CGFloat = 2.0
let horizontalSpacing:CGFloat = 5
attributes?.forEach { layoutAttribute in
if layoutAttribute.frame.origin.y >= maxY
|| layoutAttribute.frame.origin.x == sectionInset.left {
leftMargin = sectionInset.left
}
if layoutAttribute.frame.origin.x == sectionInset.left {
leftMargin = sectionInset.left
}
else {
layoutAttribute.frame.origin.x = leftMargin
}
leftMargin += layoutAttribute.frame.width + horizontalSpacing
maxY = max(layoutAttribute.frame.maxY, maxY)
}
return attributes
}
在ViewController中 - 您必须将流程布局添加到集合视图中才能使其工作:
let layout = MyLeftCustomFlowLayout()
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
myCollectionViewReference.collectionViewLayout = layout
我认为Collection View的实现绝对可以简化,但我会更多地研究它,因为我可以看到它有多强大。
答案 1 :(得分:5)
在Swift 5中
使用UICollectionViewFlowLayout将单元格向左对齐,如下所示
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
self.collectionView.collectionViewLayout = layout
答案 2 :(得分:0)
当显示最后一个单元格(仅)时,请尝试查看调试 - &gt; 捕获视图层次结构(即假设您在模拟器中运行)。我的预感:一旦你只有一个
,你的细胞就会变大答案 3 :(得分:0)
如果与普通UICollectionViewFlowLayout
的唯一要求差异是确保第一项始终保持左对齐,则只需执行以下操作就足够了:
class MyCustomFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
attributes?.first?.frame.origin.x = sectionInset.left
return attributes
}
}
其缺点是它仅适用于第一部分的第一项。另外,我们可以使用元素属性附带的索引路径:
class MyCustomFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
attributes?.forEach { (elementAttributes) in
if elementAttributes.indexPath.item == 0 {
elementAttributes.frame.origin.x = sectionInset.left
}
}
return attributes
}
}
通过(在上面的示例中)检查here中记录的elementAttributes.representedElementCategory
,也可以仅定位单元格。
答案 4 :(得分:0)
这是我从 here 那里得到的。它对我有用,将估计大小设置为无