Центральная ячейка в UICollectionView с горизонтальным режимом и PagingEnabled - PullRequest
0 голосов
/ 26 декабря 2018

У меня проблема с UICollectionView.Мои ячейки короче ширины представления коллекции, и поэтому я не могу центрировать ячейку после прокрутки.Я пытался найти любое рабочее решение здесь, но безрезультатно.Мое предположение - сделать коллекцию как в магазине приложений.

Код выглядит так:

func prepareCollectionView() {
    collectionView.delegate = self
    collectionView.dataSource = self
    collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellID)
    collectionView.showsVerticalScrollIndicator = false
    collectionView.showsHorizontalScrollIndicator = false
    collectionView.isPagingEnabled = ture
    if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.scrollDirection = .horizontal
        layout.sectionInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
    }
}

func scrollTo(_ page: Int) -> CGPoint {
    let cellWidth = collectionView.bounds.width - 20 * 2
    let nextCellWidth =  CGFloat(page) * (cellWidth + 10)
    return CGPoint(x: nextCellWidth, y: 0)
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath)
    cell.backgroundColor = .blue
    cell.layer.cornerRadius = 20
    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: collectionView.bounds.width - 20 * 2, height: collectionView.bounds.height)
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    let currentXPosition = scrollView.contentOffset.x
    let cellWidth = collectionView.bounds.width - 20 * 2
    let isNextPage = currentXPosition.truncatingRemainder(dividingBy: cellWidth) > cellWidth / 2 ? true : false
    let currentPage = isNextPage ? Int(currentXPosition / cellWidth) + 1 : Int(currentXPosition / cellWidth)
    scrollView.scrollRectToVisible(CGRect(origin: scrollTo(currentPage), size: CGSize(width: 0, height: 0)), animated: true)
}

Теперь это выглядит так:

enter image description here

Если бы я мог попросить несколько советов, как было бы по центру моей ячейки, было бы здорово:)

WORKING SOLUTION В соответствии с @canister_exister я создал пользовательские UICollectionViewFlowLayout, которые выглядятвот так:

class CustoFlowLayout: UICollectionViewFlowLayout {

//MARK: - Variables

private var isSetupDone = false

override func prepare() {
    super.prepare()
    if !isSetupDone {
        setup()
        isSetupDone.toggle()
    }
}

private func setup() {
    scrollDirection = .horizontal
    minimumLineSpacing = 10
    guard let collectionView = collectionView else { return }
    itemSize = CGSize(width: collectionView.frame.width - 40, height: collectionView.frame.height)
    collectionView.decelerationRate = UIScrollView.DecelerationRate.fast
    sectionInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)

}

override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
    guard let collectionView = collectionView else { return .zero }
    let layoutAttributes = layoutAttributesForElements(in: collectionView.bounds)
    let centerOffset = collectionView.bounds.size.width / 2
    let offsetWithCenter = proposedContentOffset.x + centerOffset
    guard let contestAttribute = layoutAttributes else { return .zero }
    let att = contestAttribute.sorted(by: { abs($0.center.x - offsetWithCenter) < abs($1.center.x - offsetWithCenter) }).first ?? UICollectionViewLayoutAttributes()
    return CGPoint(x: att.center.x - centerOffset, y: 0)
}
}

Работает правильно!

...