swiftcollectionviewpagecontrol

CollectionView + Page control


I've collectionView where every cell is a page (the cell occupies the whole screen in portrait mode and 2 cells in landscape mode). I'm trying to add the current page number/the total number of pages (i.e 1/30) what I got so far 1/0 --> one is the current page number and 0 is the total number of pages.

there are two problems:

the code I use:

func scrollViewDidScroll(_ scrollView: UIScrollView) {

        if pageControl.currentPage < pages.count {
                   pageControl.currentPage += 1
                    numberOfPagesLabel.text = "\(pageControl.currentPage + 1)/\(pages.count)"
        } else if pageControl.currentPage != 0 {
                    pageControl.currentPage -= 1
                    numberOfPagesLabel.text = "\(pageControl.currentPage - 1)/\(pages.count)"
                }
    }

class DetailsViewController: UIViewController, UICollectionViewDelegate,  UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate  {

     private var collectionView: UICollectionView!
    
    let pageControl = UIPageControl (frame: CGRect(x: 20, y: 120, width: 44, height: 44))
    let numberOfPagesLabel = UILabel (frame: CGRect(x: 20, y: 0, width: 44, height: 44))

    
    private var pages = [Pages]() {
      didSet {
        DispatchQueue.main.async {
          self.collectionView.reloadData()
        }
      }
    }
    
     override func viewDidLoad() {
         super.viewDidLoad()
      
        numberOfPagesLabel.layer.cornerRadius = 15.0
        numberOfPagesLabel.clipsToBounds = true
        numberOfPagesLabel.center.x = self.view.center.x
        numberOfPagesLabel.center.y = self.view.center.y+350

         
         self.view.addSubview(collectionView)
        self.view.addSubview(pageControl)
        self.view.addSubview(numberOfPagesLabel)

     }

         override func viewDidAppear(_ animated: Bool) {
           super.viewDidAppear(true)
            
            collectionViewLayout()
            collectionView.delegate = self
            collectionView.dataSource = self

            }
  

    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {

        if pageControl.currentPage < pages.count {
                   pageControl.currentPage += 1
                    numberOfPagesLabel.text = "\(pageControl.currentPage + 1)/\(pages.count)"
        } else if pageControl.currentPage != 0 {
                    pageControl.currentPage -= 1
                    numberOfPagesLabel.text = "\(pageControl.currentPage - 1)/\(pages.count)"
                }
    }
    
     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return pages.count
         }


     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "colCell7", for: indexPath) as! colCell7
        
         let book = pages[indexPath.row]
         cell.setupCell(for: book)
         return cell
     }



     func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        if UIWindow.isLandscape {
            return CGSize(width: (collectionView.frame.size.width)/2, height: (collectionView.frame.size.height))
        }

        else {            return CGSize(width: (collectionView.frame.size.width), height: (collectionView.frame.size.height))
        }
    }

    
 func collectionViewLayout() {
        
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0), collectionViewLayout: layout)
       collectionView.backgroundColor = .white

       collectionView.showsHorizontalScrollIndicator = false
       collectionView.showsVerticalScrollIndicator = false
       collectionView.isPagingEnabled = true


        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.register(colCell7.self, forCellWithReuseIdentifier: "colCell7")
        collectionView.isScrollEnabled = true
       collectionView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
       layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height)
              layout.minimumLineSpacing = 0
              layout.minimumInteritemSpacing = 0
       layout.itemSize = CGSize(width: view.frame.width/2, height:view.frame.height )
    }
}

Solution

  • I figured it out. the code below work with landscape orintation (with 2 cells) and portrait orintation (with 1 cell) I still have one problem the counting doesn't appear until the scrolling starts.

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            if UIWindow.isLandscape {
                let x = scrollView.contentOffset.x
                let w = scrollView.bounds.size.width/2
                let currentPage = Int(ceil(x/w))
            numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 2)"
                            pageControl.currentPage = Int(currentPage)        }
            else
            {
                let x = scrollView.contentOffset.x
                let w = scrollView.bounds.size.width
                let currentPage = Int(ceil(x/w))
            numberOfPagesLabel.text = "\(self.pages.count)/\(currentPage + 1)"
                            pageControl.currentPage = Int(currentPage)
            }
    
    extension UIWindow {
        static var isLandscape: Bool {
            if #available(iOS 13.0, *) {
                return UIApplication.shared.windows
                    .first?
                    .windowScene?
                    .interfaceOrientation
                    .isLandscape ?? false
            } else {
                return UIApplication.shared.statusBarOrientation.isLandscape
            }
        }
    
    }