Что именно происходит в UICollectionViewFlowLayout при перетаскивании ячейки с помощью функции перетаскивания IOS 11? - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь реализовать Drag & Drop для своих UICollectionViews (а также хочу узнать о UICollectionViewLayout s).Я реализовал dragDelegate/dropDelegate методы для представления коллекции, и теперь я могу перетаскивать ячейки вокруг.

Я также установил намерение перетаскивания предложения на .insertAtDestinationIndexPath, чтобы ячейки перемещались, чтобы освободить место для перетаскиваемой ячейки (поэтому компоновка изменяется при наведении на нее перетаскиваемой ячейки).

Это отлично работает с UICollectionViewFlowLayout.Однако я использую IGListKit, который в основном использует раздел для каждой ячейки в представлении коллекции.И секции обычно всегда отображаются на новой строке, но я хочу, чтобы на одной строке было несколько секций (= ячеек).Вот почему я делю на подклассы макет:

class CustomFlowLayout: UICollectionViewFlowLayout {

override var collectionViewContentSize: CGSize {
    return CGSize(width: contentWidth, height: contentHeight)
}

fileprivate var contentHeight: CGFloat = 0

fileprivate var contentWidth: CGFloat {
    guard let collectionView = collectionView else {
        return 0
    }
    let insets = collectionView.contentInset
    return collectionView.bounds.width - (insets.left + insets.right)
}

var cachedAttribtues = [UICollectionViewLayoutAttributes]()

override func prepare() {
    super.prepare()
    cachedAttribtues = []
    guard let collectionView = collectionView else { return }
    let sectionCount = collectionView.numberOfSections

    var columnWidth = contentWidth / 2 - 5

    var yOffset: CGFloat = 0
    var column = 0

    for section in 0..<sectionCount {
        let indexPath = IndexPath(item: 0, section: section)

        let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
        attributes.frame = CGRect(x: CGFloat(column) * columnWidth, y: yOffset, width: columnWidth, height: 150)

        yOffset += CGFloat(column) * 200
        column = (column + 1) % 2


        cachedAttribtues.append(attributes)
    }

}

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

    for attributes in cachedAttribtues {
        if attributes.frame.intersects(rect) {
            visibleLayoutAttributes.append(attributes)
        }
    }

    return visibleLayoutAttributes
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
    return cachedAttribtues[indexPath.section]
}
}

Это не красиво, это не оптимально, это просто проверить вещи .Моя проблема сейчас заключается в том, что он падает, когда я перетаскиваю ячейку и перемещаю ее:

Завершение приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «UICollectionView получил атрибуты макета для ячейки с индексным путемэтого не существует: {length = 2, path = 0 - 0} '

Я понятия не имею, что здесь происходит и почему.Есть кое-что, что меняется, когда ячейки пытаются двигаться (чтобы освободить место для перетаскиваемой ячейки, которая зависает над ней).

Было бы замечательно, если бы кто-то мог сказать мне, что мне нужно позаботиться, когда я хочу поддержатьперетаскивая ячейки с моим собственным макетом.Я смотрел почти все сессии WWDC на Drag & Drop, но я не могу найти решение для этого.

Спасибо!

ОБНОВЛЕНИЕ: Я кое-что узнал.Внутри layoutAttributesForElements(in:) я постоянно распечатываю все видимые IndexPaths в UICollectionView.В начале это выглядит так:

[[0, 0], [2, 0], [1, 0], [3, 0]]

Прямо перед сбоем приложения оно выглядит так:

[[0, 1], [2, 0], [0, 0], [3, 0]]

Итак, я думаю, что проблема заключается в следующем: в prepare() я создаю UICollectionViewLayoutAttributes для всех разделов с индексом 0. Поэтому, когда я передаю атрибуты, которые находятся в данном CGRect, он вернет section 1, item 0, но этого не существует, так как он каким-то образом стал section 0, item 1 (я думаю).

Так что каким-то образом система хочет разместить ячейку внутри секции 0 в пункте 1. Почему это так?И что я могу сделать с этой информацией?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...