Остановить одиночную ячейку UICollectionView Пролистать в центр экрана

Я пытаюсь понять, почему Collection View поддерживает выравнивание центра только последней ячейки в коллекции.
 Я создал простое представление коллекции на основе потока. Я использую флаг Autolayout, который я не уверен, вызывает эту проблему.

Всякий раз, когда я удаляю ячейку из представления "Коллекция", первые несколько, кажется, работают нормально и рулон влево. Однако, когда я удаляю второй последний, то внезапно последняя ячейка изменяется от выравнивания влево до выравнивания по центру. У кого-нибудь есть объяснение? Кажется странным.

Как сделать так, чтобы все ячейки переместились влево и оставались выровненными влево.

Изменить: вот отладка hierachy: http://imgur.com/a/NxidO

Вот представление Behavior

Центрирование коллекционирования

Я сделал простой 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 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:/img/f82d1d57f16642dfcd8108a8f40804d5.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])
    }

Ответы

Ответ 1

Мне удалось решить это, используя следующие два шага: 1. Записал ошибку с Apple о странном поведении, которое я заметил о изменении поведения ячейки при использовании UICollectionViewFlowLayoutAutomaticSize 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 может быть упрощена, но я собираюсь изучить ее больше, поскольку я могу видеть, насколько она эффективна.

Ответ 2

Когда отображается последняя ячейка (только), попробуйте просмотреть отладку → иерархию представления захвата (т.е. предположим, что вы запустили в симуляторе). Моя догадка: ваша ячейка растет в размерах, когда у вас есть только один левый