UIKit Dynamics в Collection View всегда заканчивается хаосом - PullRequest
0 голосов
/ 09 мая 2019

При прокрутке с моим «упругим макетом потока» (предназначенным для воспроизведения эффекта прокрутки в сообщениях) начальная прокрутка работает хорошо, но повторяющаяся прокрутка заканчивается, когда все ячейки постоянно подпрыгивают по всему экрану и отклоняются от вертикальной оси..

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

Как предотвратить движение по горизонтальной оси и как обеспечить постоянное появление ячеекв конце концов

class SpringyColumnLayout: UICollectionViewFlowLayout {
    private lazy var dynamicAnimator = UIDynamicAnimator(collectionViewLayout: self)

    override func prepare() {
        super.prepare()

        guard let cv = collectionView else { return }

        let availableWidth = cv.bounds.inset(by: cv.layoutMargins).width

        let minColumnWidth: CGFloat = 300
        let maxNumberOfColumns = Int(availableWidth / minColumnWidth)
        let cellWidth = (availableWidth / CGFloat(maxNumberOfColumns))
            .rounded(.down)

        self.itemSize = CGSize(width: cellWidth, height: 70)

        self.sectionInset = UIEdgeInsets(
            top: minimumInteritemSpacing,
            left: 0,
            bottom: 0,
            right: 0
        )

        self.sectionInsetReference = .fromSafeArea

        if dynamicAnimator.behaviors.isEmpty {
            let contentSize = collectionViewContentSize
            let contentBounds = CGRect(origin: .zero, size: contentSize)
            guard let items = super.layoutAttributesForElements(in: contentBounds)
                else { return }

            for item in items {
                let spring = UIAttachmentBehavior(
                    item: item,
                    attachedToAnchor: item.center
                )
                spring.length = 0
                spring.damping = 0.8
                spring.frequency = 1

                self.dynamicAnimator.addBehavior(spring)
            }
        }
    }

    override func layoutAttributesForElements(
        in rect: CGRect
    ) -> [UICollectionViewLayoutAttributes]? {
        return dynamicAnimator.items(in: rect) as? [UICollectionViewLayoutAttributes]
    }

    override func layoutAttributesForItem(
        at indexPath: IndexPath
    ) -> UICollectionViewLayoutAttributes? {
        return dynamicAnimator.layoutAttributesForCell(at: indexPath)
    }

    override func shouldInvalidateLayout(
        forBoundsChange newBounds: CGRect
    ) -> Bool {
        let scrollView = self.collectionView!

        let scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y
        let touchLocation = scrollView.panGestureRecognizer
            .location(in: scrollView)

        for case let spring as UIAttachmentBehavior in dynamicAnimator.behaviors {
            let anchorPoint = spring.anchorPoint
            let yDistanceFromTouch = abs(touchLocation.y - anchorPoint.y)
            let xDistanceFromTouch = abs(touchLocation.x - anchorPoint.x)
            let scrollResistance = (yDistanceFromTouch + xDistanceFromTouch) / 1500

            let item = spring.items.first!
            var center = item.center
            if scrollDelta < 0 {
                center.y += max(scrollDelta, scrollDelta * scrollResistance)
            } else {
                center.y += min(scrollDelta, scrollDelta * scrollResistance)
            }
            item.center = center

            dynamicAnimator.updateItem(usingCurrentState: item)
        }

        return false
    }
}
...