Paging UICollectionView by cells, not screen

前端 未结 22 2059
予麋鹿
予麋鹿 2020-12-04 05:00

I have UICollectionView with horizontal scrolling and there are always 2 cells side-by-side per the entire screen. I need the scrolling to stop at the begining

22条回答
  •  时光取名叫无心
    2020-12-04 05:40

    Swift 5

    I've found a way to do this without subclassing UICollectionView, just calculating the contentOffset in horizontal. Obviously without isPagingEnabled set true. Here is the code:

    var offsetScroll1 : CGFloat = 0
    var offsetScroll2 : CGFloat = 0
    let flowLayout = UICollectionViewFlowLayout()
    let screenSize : CGSize = UIScreen.main.bounds.size
    var items = ["1", "2", "3", "4", "5"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumLineSpacing = 7
        let collectionView = UICollectionView(frame: CGRect(x: 0, y: 590, width: screenSize.width, height: 200), collectionViewLayout: flowLayout)
        collectionView.register(collectionViewCell1.self, forCellWithReuseIdentifier: cellReuseIdentifier)
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.backgroundColor = UIColor.clear
        collectionView.showsHorizontalScrollIndicator = false
        self.view.addSubview(collectionView)
    }
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        offsetScroll1 = offsetScroll2
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        offsetScroll1 = offsetScroll2
    }
    
    func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer){
        let indexOfMajorCell = self.desiredIndex()
        let indexPath = IndexPath(row: indexOfMajorCell, section: 0)
        flowLayout.collectionView!.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
        targetContentOffset.pointee = scrollView.contentOffset
    }
    
    private func desiredIndex() -> Int {
        var integerIndex = 0
        print(flowLayout.collectionView!.contentOffset.x)
        offsetScroll2 = flowLayout.collectionView!.contentOffset.x
        if offsetScroll2 > offsetScroll1 {
            integerIndex += 1
            let offset = flowLayout.collectionView!.contentOffset.x / screenSize.width
            integerIndex = Int(round(offset))
            if integerIndex < (items.count - 1) {
                integerIndex += 1
            }
        }
        if offsetScroll2 < offsetScroll1 {
            let offset = flowLayout.collectionView!.contentOffset.x / screenSize.width
            integerIndex = Int(offset.rounded(.towardZero))
        }
        let targetIndex = integerIndex
        return targetIndex
    }
    

提交回复
热议问题