1

I've updated my Xcode to the latest version, currently it's 10.2.1(10E1001) and migrated my project from Swift 4 to Swift 5.

It made me some troubles, but finally I've built my project and it works correctly from debug version on my iPhone.

After that I've had few troubles with archiving my project (maybe it could be a reason)

I've upload it in App Store and after that tried my app at TestFlight. Plus, for some reason few code in my project works wrong.

It seems like collectionView(didSelectItemAtIndexPath...) doesn't work (but it perfectly works in Xcode) and my custom layout of collectionView doesn't work too (but also works on Debug).

It seems like layout works wrong, but I can't understand what's the difference between Debug and Release version except provisioning profile.

I can share you more videos, code, w/e you need, I really need to resolve this issue.

I've not found anything else like that in the web

I've taken that custom layout code from here https://codereview.stackexchange.com/questions/197017/page-and-center-uicollectionview-like-app-store

    class SnapPagingLayout: UICollectionViewFlowLayout {
    private var centerPosition = true
    private var peekWidth: CGFloat = 0
    private var indexOfCellBeforeDragging = 0

    convenience init(centerPosition: Bool = true, peekWidth: CGFloat = 40, spacing: CGFloat? = nil, inset: CGFloat? = nil) {
        self.init()

        self.scrollDirection = .horizontal
        self.centerPosition = centerPosition
        self.peekWidth = peekWidth

        if let spacing = spacing {
            self.minimumLineSpacing = spacing
        }

        if let inset = inset {
            self.sectionInset = UIEdgeInsets(top: 0, left: inset, bottom: 0, right: inset)
        }
    }

    override func prepare() {
        super.prepare()

        guard let collectionView = collectionView else { return }
        self.itemSize = calculateItemSize(from: collectionView.bounds.size)
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        guard let collectionView = collectionView,
            !newBounds.size.equalTo(collectionView.bounds.size) else {
                return false
        }

        itemSize = calculateItemSize(from: collectionView.bounds.size)
        return true
    }
}
private extension SnapPagingLayout {

    func calculateItemSize(from bounds: CGSize) -> CGSize {
        return CGSize(
            width: bounds.width - peekWidth * 2,
            height: (bounds.width - peekWidth * 2) / 1.77
        )
    }

    func indexOfMajorCell() -> Int {
        guard let collectionView = collectionView else { return 0 }

        let proportionalOffset = collectionView.contentOffset.x
            / (itemSize.width + minimumLineSpacing)

        return Int(round(proportionalOffset))
    }


}

extension SnapPagingLayout {

    func willBeginDragging() {
        indexOfCellBeforeDragging = indexOfMajorCell()
    }

    func willEndDragging(withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        guard let collectionView = collectionView else { return }

        // Stop scrollView sliding
        targetContentOffset.pointee = collectionView.contentOffset

        // Calculate where scrollView should snap to
        let indexOfMajorCell = self.indexOfMajorCell()

        guard let dataSourceCount = collectionView.dataSource?.collectionView(collectionView, numberOfItemsInSection: 0),
            dataSourceCount > 0 else {
                return
        }

        // Calculate conditions
        let swipeVelocityThreshold: CGFloat = 0.3 // After some trail and error
        let hasEnoughVelocityToSlideToTheNextCell = indexOfCellBeforeDragging + 1 < dataSourceCount && velocity.x > swipeVelocityThreshold
        let hasEnoughVelocityToSlideToThePreviousCell = indexOfCellBeforeDragging - 1 >= 0 && velocity.x < -swipeVelocityThreshold
        let majorCellIsTheCellBeforeDragging = indexOfMajorCell == indexOfCellBeforeDragging
        let didUseSwipeToSkipCell = majorCellIsTheCellBeforeDragging
            && (hasEnoughVelocityToSlideToTheNextCell || hasEnoughVelocityToSlideToThePreviousCell)

        guard didUseSwipeToSkipCell else {
            // Better way to scroll to a cell
            collectionView.scrollToItem(
                at: IndexPath(row: indexOfMajorCell, section: 0),
                at: centerPosition ? .centeredHorizontally : .left, // TODO: Left ignores inset
                animated: true
            )

            return
        }

        let snapToIndex = indexOfCellBeforeDragging + (hasEnoughVelocityToSlideToTheNextCell ? 1 : -1)
        var toValue = CGFloat(snapToIndex) * (itemSize.width + minimumLineSpacing)

        if centerPosition {
            // Back up a bit to center
            toValue = toValue - peekWidth + sectionInset.left
        }

        // Damping equal 1 => no oscillations => decay animation
        UIView.animate(
            withDuration: 0.3,
            delay: 0,
            usingSpringWithDamping: 1,
            initialSpringVelocity: velocity.x,
            options: .allowUserInteraction,
            animations: {
                collectionView.contentOffset = CGPoint(x: toValue, y: 0)
                collectionView.layoutIfNeeded()
        },
            completion: nil
        )
    }
}

I wanna see page and center collection view like in App Store. And also I wanna make my didSelect-method work correctly.

acarlstein
  • 1,799
  • 2
  • 13
  • 21

1 Answers1

0

This is a bug for Swift 5.0 compiler related to this references:

https://bugs.swift.org/browse/SR-10257

.

Update: Further searching found an temporary answer at this link on Stackoverflow

You can work around it by explicitly tagging it with @objc for now.

bakhshaei
  • 36
  • 4