swiftuicollectionviewuipagecontrol

Swift CollectionView slider with preview of next page


I have slider which display image on each cell. What I want to do, is display 10% of next image on current page and slider it to next page. Each image should be centered in own page (3 in total).

extension OnboardingViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width - 200, height: view.frame.height)
}

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    let cellWidth : CGFloat = view.frame.width - 200

    let numberOfCells = floor(self.view.frame.size.width / cellWidth)
    let edgeInsets = (self.view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)

    return UIEdgeInsets(top: 15, left: edgeInsets, bottom: 0, right: edgeInsets)
}

enter image description here }


Solution

  • What i did is... i put left edge inset. Made my cell smaller, like 0.74 of initial size, i add 2 methods to control my slides when i drag slide... then i add animation to my custom cell with flag previewed. So.. my initial slide always previewed and has size 1.0, all other has 0.9 size, when i drag image i change previewed state to false for all slides and do true only for presented.

    0.74 is size of my cell

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        let cellWidth : CGFloat = view.frame.width * 0.74
    
        let numberOfCells = floor(self.view.frame.size.width / cellWidth)
        let edgeInsets = (self.view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)
    
        return UIEdgeInsets(top: 0, left: edgeInsets, bottom: 0, right: edgeInsets)
    }
    

    i found custom size to my case

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

    And i wrote 2 methods to control my slides

    func scrollViewWillEndDragging(_ scrollView: UIScrollView,
                                   withVelocity velocity: CGPoint,
                                   targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let x = targetContentOffset.pointee.x
    
        pageControl.currentPage = Int(x / view.frame.width * 0.74)
        let last = viewModel.getNumberOfItems() - 1
        if pageControl.currentPage == last {
            btnStart.isHidden = false
            imbBtnStartBg.isHidden = false
        } else {
            btnStart.isHidden = true
            imbBtnStartBg.isHidden = true
        }
    
    }
    
    func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
        let pageWidth = view.frame.width * 0.74
    
        let page = floor((collectionView.contentOffset.x - pageWidth / 2) / pageWidth) + 1
        let xOffset: CGFloat = page * pageWidth
        collectionView.setContentOffset(CGPoint(x: xOffset, y: 0.0), animated: true)
        pageControl.currentPage = Int(page)
        if Int(page) == 2{
            btnStart.isHidden = false
            imbBtnStartBg.isHidden = false
        } else {
            btnStart.isHidden = true
            imbBtnStartBg.isHidden = true
        }
        for i in 0..<viewModel.onBoardingModels.count{
            viewModel.onBoardingModels[i].previewed = false
        }
        viewModel.onBoardingModels[Int(page)].previewed = true
        collectionView.reloadData()
    }
    

    Also i add animation to my cell

    UIView.animate(withDuration: 0.5, animations: {
            self.imgv.transform = model.previewed ? CGAffineTransform(scaleX: 1, y: 1) : CGAffineTransform(scaleX: 0.9, y: 0.9)
        })