web-dev-qa-db-fra.com

Comment connecter UIPageControl à UICollectionView (Swift)

J'utilise actuellement un UICollectionView pour afficher 3 images (chaque image s'étend sur toute la cellule). J'ai également un UIPageControl que j'ai placé au-dessus de l'UICollectionView. Ce que je veux arriver, c'est que l'UIPageControl affiche le nombre d'images (qui dans ce cas est 3), et aussi l'image que l'utilisateur regarde actuellement. L'effet que j'essaie d'obtenir est celui de l'application Instagram.

La manière que j'utilise actuellement pour obtenir cet effet est de placer la mise à jour de UIPageControl dans la fonction willDisplay de UICollectionView, comme ceci:

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    pictureDots.currentPage = indexPath.item
}

Cela parvient à connecter correctement l'effet de pagination entre la vue de collection et le contrôle de page. Cependant, le problème que j'ai est que l'UIPageControl commence par dire que l'utilisateur est sur la troisième image, même s'il affiche la première image.

Quelqu'un sait-il pourquoi cela se produit et comment résoudre ce problème?

9
kbunarjo

Ajoutez d'abord votre UIPageControl dans votre storyboard avec votre UICollectionView, puis connectez-les en tant que prises à votre contrôleur de vue.

@IBOutlet var pageControl: UIPageControl!
@IBOutlet var collectionView: UICollectionView!

Ajustez votre méthode numberOfItemsInSection dans UICollectionViewDataSource pour que le nombre de contrôles de page soit toujours égal au nombre de cellules dans la vue de collection.

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

    let count = ...

    pageControl.numberOfPages = count
    pageControl.isHidden = !(count > 1)

    return count
}

Enfin, en utilisant le UIScrollViewDelegate, nous pouvons dire sur quelle cellule le UICollectionView s'arrête. Si vous n'utilisez pas un UICollectionViewController, vous devrez peut-être ajouter le protocole délégué.

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

    pageControl?.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}

Ceci est possible car un UICollectionView est en fait un UIScrollView sous le capot.

24
Callam

Étape 1 Créez les variables pour la vue de collection et le contrôle de page

@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet var pageControl:UIPageControl!     

Étape 2 Définissez le nombre de pages de contrôle de page

override func viewDidLoad() {
    super.viewDidLoad()         
    self.pageControl.numberOfPages = procedures.count
    //Set the delegate
    self.collectionView.delegate = self
}

* Étape Dans la fonction scrollViewDidScroll, calculez la largeur de la cellule de collecte et l'index de la page en cours.

    extension YourCollectionVC: UICollectionViewDataSource, UICollectionViewDelegate {
            override func scrollViewDidScroll(_ scrollView: UIScrollView) {
                let witdh = scrollView.frame.width - (scrollView.contentInset.left*2)
                let index = scrollView.contentOffset.x / witdh
                let roundedIndex = round(index)
                self.pageControl?.currentPage = Int(roundedIndex)
            }
}

Remarque: Ceci est pour la vue de collection affichée horizontalement, pour la direction verticale, changez la méthode.

Testé en Swift 4.

10