web-dev-qa-db-fra.com

Pagination horizontale UICollectionView avec espace entre les pages

Je cherche un moyen de remplacer la pagination horizontale native UIPageViewController par une UICollectionView.

jusqu'à présent, j'ai fait ce qui suit:

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.itemSize = collectionView.frame.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 10

collectionView.setCollectionViewLayout(layout, animated: false)
collectionView.isPagingEnabled = true
collectionView.alwaysBounceVertical = false

cela fonctionne bien et j'obtiens un effet de pagination horizontale.

Maintenant, je veux ajouter un espace horizontal entre les pages (comme vous le ferez avec UIPageViewControllerOptionInterPageSpacingKey sur UIPageViewController)

jusqu'à présent, je n'ai pas pu trouver un moyen d'ajouter des espaces sans endommager l'effet de pagination. im recherche le même comportement qu'avec UIPageViewController: la cellule doit remplir toute la largeur de l'écran et l'espace entre les cellules ne doit être visible que lors du changement de page.

13
Eyal

Première solution:

  1. collectionView.isPagingEnabled = false
  2. ajouter un minimumLineSpacing pour la distance entre les pages
  3. mettre en place targetContentOffsetForProposedContentOffset:withScrollingVelocity: pour déplacer le contentOffset vers la page la plus proche. Vous pouvez calculer la page avec des mathématiques simples en fonction de vos itemSize et minimumLineSpacing, mais cela peut prendre un peu de travail pour bien faire les choses.

Deuxième solution:

  1. collectionView.isPagingEnabled = true
  2. ajouter un minimumLineSpacing pour la distance entre les pages
  3. la taille de la pagination est basée sur les limites de la collectionView. Alors agrandissez la collectionView puis screenSize. Par exemple, si vous avez un minimumLineSpacing de 10, définissez le cadre de la collectionView sur {0, -5, largeur + 10, hauteur}
  4. définissez un contentInset égal à minimumLineSpacing pour que le premier et le dernier élément apparaissent correctement.
20
Jon Rose
  • Par défaut, minimumLineSpacing d'UICollectionViewFlowLayout est 10.0, lorsque l'élément de collectionView est rempli horizontalement (itemSize.width = collectionView.bounds.width) et que collectionView est activé par la pagination, une valeur supérieure à zéro 'minimumLineSpacing' entraînera une performance non voulue: commencer à partir de la deuxième page, chaque page a un écart qui sera accumulé par numéro de page.
  • Il semble que nous pouvons étendre la largeur de collectionView de "minimumLineSpacing" pour résoudre ce problème. Mais la pratique nie cette solution: lorsqu'il y a des pages de remorquage ou plus, collectionView ne donnera pas au dernier un 'lineSpacing', donc c'est 'contentSize' ne suffit pas pour montrer complètement le contenu de cette page, ce qui signifie que si le 'minimumLineSpacing' était 10.0 , la fin de la dernière page dépasserait le contentSize de collectionView de 10,0.
  • Enfin, j'utilise la solution simple suivante pour insérer une marge entre chaque élément (comme la préformance d'UIScrollView): étendez la largeur de chaque collectionViewItem d'une valeur fixe `` pageSpacing '' (telle que 10.0) et étendez également la largeur de collectionView de la même valeur. Et n'oubliez pas que, lorsque les sous-vues de collevtionViewCell sont mises en page, il y a un espacement supplémentaire qui n'est pas destiné à afficher le contenu réel.

Voici le code écrit en Swift 3.1, je suis sûr qu'il comprend facilement pour vous:

let pageSpacing: CGFloat = 10

class ViewController: UITableViewController {
     override func viewDidLoad() {
        super.viewDidLoad()

        let layout = UICollectionViewFlowLayout()
        layout.itemSize                = CGSize(width: view.frame.width + pageSpacing, height: view.frame.height)
        layout.scrollDirection         = .horizontal
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing      = 0

        let frame = CGRect(x: 0, y: 0, width: view.frame.width + pageSpacing, height: view.frame.height)
        let collectionView = UICollectionView(frame: frame, collectionViewLayout: layout)
        view.addSubview(collectionView)
    }
}

class MyCell: UICollectionViewCell {
    var fullScreenImageView = UIImageView()
    override func layoutSubviews() {
        super.layoutSubviews()
        fullScreenImageView.frame = CGRect(x: 0, y: 0, width: frame.width - pageSpacing, height: frame.height)
    }
}

J'espère que cela peut vous aider.

2
Rick