停止单个 UICollectionView 单元格流向屏幕中心 [英] Stop Single UICollectionView cell Flowing to the centre of the screen

查看:21
本文介绍了停止单个 UICollectionView 单元格流向屏幕中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解为什么集合视图保持中心对齐集合中的最后一个单元格.
我创建了一个简单的基于流布局的集合视图.我正在使用 Autolayout 标志 - 我不确定是否会导致此问题.

每当我从集合视图中删除一个单元格时 - 前几个似乎工作正常并滚动到左侧.但是,当我删除倒数第二个时,突然间最后一个单元格从左对齐变为居中对齐.有人有解释吗?好像很奇怪.

如何使所有单元格向左滚动并保持与左侧对齐.

这是视图层次调试:

我做了一个简单的github来演示它:https://github.com/grantkemp/CollectionViewIssue

这里是代码:

 var dataforCV = ["short","longer phrase", "Super long Phrase"]覆盖 func viewDidLoad() {super.viewDidLoad()demoCollectionView.reloadData()让布局 = UICollectionViewFlowLayout()//错误描述 - >如果 UICollectionViewFlowLayoutAutomaticSize 只有一个单元格,它将居中对齐布局 - 但如果有多个单元格,它将左对齐内容.//我希望这种行为始终保持内容左对齐.//如何重复:如果您注释掉 UICollection View Flow Layout Automatic Size,则集合视图将显示 3 个左对齐单元格,并且无论您删除多少个单元格,它将继续左对齐所有内容.//但是:如果你离开打开 UICollection View Flow Layout Automatic Size - 那么它最初会显示 3 个左对齐的单元格,然后当您单击删除每个单元格时,它们将保持左对齐,直到最后一个单元格将突然在集合视图中居中对齐//录屏见这里:https://i.stack.imgur.com/bledY.gif//查看层次结构调试屏幕:http://imgur.com/a/NxidOlayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize//<-- 结束错误描述demoCollectionView.collectionViewLayout = 布局}//标记:CollectionViewfunc collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) ->UICollectionViewCell {让 cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as?集合细胞单元格?.text.text = dataforCV[indexPath.row]返回细胞!}func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) ->诠释{返回数据forCV.count}//如果选中,则从数组中删除项目func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {dataforCV.remove(在:indexPath.row)demoCollectionView.deleteItems(在:[indexPath])}

解决方案

我设法通过以下两个步骤解决了这个问题:

  1. 向 Apple 记录了一个关于我注意到使用 UICollectionViewFlowLayoutAutomaticSize
  2. 时单元格行为发生变化的奇怪行为的错误
  3. 我通过创建修改后的 CustomViewFlowLayout 做了一个解决方法(找不到我看到使用这种方法的原始 SO/github 问题 - 如果我找到它,我会添加它)然后我添加了UICollectionViewFlowLayoutAutomaticSize 设置 - 它运行良好.

示例代码:

类 MyLeftCustomFlowLayout:UICollectionViewFlowLayout {覆盖 func layoutAttributesForElements(in rect: CGRect) ->[UICollectionViewLayoutAttributes]?{让属性 = super.layoutAttributesForElements(in: rect)var leftMargin = sectionInset.leftvar maxY: CGFloat = 2.0让 Horizo​​ntalSpacing:CGFloat = 5属性?.forEach { layoutAttribute in如果 layoutAttribute.frame.origin.y >= maxY||layoutAttribute.frame.origin.x == sectionInset.left {leftMargin = sectionInset.left}如果 layoutAttribute.frame.origin.x == sectionInset.left {leftMargin = sectionInset.left}别的 {layoutAttribute.frame.origin.x = leftMargin}leftMargin += layoutAttribute.frame.width + Horizo​​ntalSpacingmaxY = max(layoutAttribute.frame.maxY, maxY)}返回属性}

在 ViewController 中 - 您必须将流布局添加到集合视图中才能使其工作:

让 layout = MyLeftCustomFlowLayout()layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSizemyCollectionViewReference.collectionViewLayout = 布局

我认为 Collection View 的实现绝对可以简化,但我会更多地研究它,因为我可以看到它有多么强大.

I am trying to understand why Collection View keeps centre aligning just the last cell in a collection.
I have created a simple Flow layout based collection view. I am using the Autolayout flag - which I am not sure is causing this issue.

Whenever I remove a cell from the Collection view - the first few seem to work fine and roll to the left. However when I remove the second last one, then suddenly the last cell changes from being left aligned to being centre aligned. Does anyone have an explanation? It seems strange.

How do I make it so that all the cells will roll to the left and stay aligned to the left.

Edit: here is the view hierachy debugging: http://imgur.com/a/NxidO

Here is the view Behaviour

I have made a simple github to demo it: https://github.com/grantkemp/CollectionViewIssue

and here is the code:

        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 UICollection​View​Flow​Layout​Automatic​Size 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 UICollection​View​Flow​Layout​Automatic​Size 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])
    }

解决方案

I managed to solve this using the below two steps:

  1. Logged a bug with Apple about the strange behaviour I noticed about the cell behaviour changing when using the UICollectionViewFlowLayoutAutomaticSize
  2. I did a workaround by creating a modified CustomViewFlowLayout ( can't find the original SO/github question where I saw this approach used - I will add it if I find it) I then added the UICollectionViewFlowLayoutAutomaticSize setting - and it's working beautifully.

Sample code:

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
    }

In the ViewController - you have to add the flow layout to the collection view to make it work:

let layout = MyLeftCustomFlowLayout() 
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
myCollectionViewReference.collectionViewLayout = layout

I think the implementation for Collection View can definitely be simplified but I am going to look into it more as I can see how powerful it is.

这篇关于停止单个 UICollectionView 单元格流向屏幕中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆