
Dans de nombreuses applications, vous pouvez rencontrer un défilement qui ne s'enroule jamais dans la direction opposée à la fin du contenu. Cette technique est standard depuis de nombreuses années sur de nombreuses plateformes. D'un autre côté, il existe de nombreuses bibliothèques tierces pour obtenir cet effet. MAIS vous n'avez besoin d'aucune bibliothèque tierce. Cette technique a une logique très simple.
Prise en charge des pages UIScrollView permet à l'utilisateur de visualiser son contenu page par page. UIScrollView active cet effet en ajustant le décalage scrollView lorsque l'utilisateur a terminé de faire glisser. Lorsque l'utilisateur fait défiler jusqu'à la fin des pages (à droite), scrollview limite l'excès de son contenu en déplaçant son décalage dans la direction opposée avec une belle animation.

Nous voulons que scrollview ne limite pas l'offset de contenu lorsque l'utilisateur veut dépasser son nombre. Par conséquent, nous devons ajouter deux pages supplémentaires à UIScrollView. La dernière page sera ajoutée à l'index zéro et la première page sera ajoutée à l'index (numberOfItems + 1). Ensuite, si l'utilisateur affiche la page «numberOfItems», le décalage du contenu x offset est défini sur 0. Si l'utilisateur affiche l'index 0, alors le décalage du contenu scrollView x sera défini sur «pageSize * numberOfItems».

La première chose à faire est de créer une nouvelle classe héritée d'UIView.

BannerView devrait être comme ci-dessous:
import UIKit class BannerView: UIView { override init(frame: CGRect) { super.init(frame: frame) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
Il n'y a rien d'inhabituel ici. Maintenant, nous devons ajouter le code scrollView et setUp pour BannerView:
import UIKit class BannerView: UIView { private let scrollView:UIScrollView = { let sc = UIScrollView(frame: .zero) sc.translatesAutoresizingMaskIntoConstraints = false sc.isPagingEnabled = true return sc }()
J'ai utilisé des cadres au lieu de la mise en page automatique pour plus de simplicité. De plus, j'ai utilisé des fermetures au lieu de délégués. Cela permet d'éviter la saleté dans le ViewController. Avec les fermetures, vous pouvez simplement utiliser bannerView comme suit:
Pour déléguer UIScrollView, j'utiliserai scrollViewDidEndDecelerating (_ scrollView: UIScrollView) au lieu de scrollViewDidScroll (_ scrollView: UIScrollView). Parce que nous n'avons pas besoin de calculer la position de swap à chaque mouvement scrollView.
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let currentPage:Int = Int(scrollView.contentOffset.x / scrollView.frame.size.width) if currentPage == 0 { self.scrollView.contentOffset = CGPoint(x: scrollView.frame.size.width * CGFloat(numberOfItems), y: scrollView.contentOffset.y) } else if currentPage == numberOfItems { self.scrollView.contentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y) } }
Et enfin, notre code sera comme ceci pour BannerView.swift:

Résumé
Ainsi, nous avons créé un composant scrollview réutilisable avec un peu de logique. Soit dit en passant, avec d'énormes quantités de données, il est préférable d'utiliser UICollectionView, car il a de meilleures performances et une meilleure gestion de la mémoire que UIScrollView. De plus, vous pouvez étendre InfiniteScrollView à l'aide des options de synchronisation ou du défilement bidirectionnel. Avec une petite amélioration, ce sera un outil vraiment réutilisable pour vos applications.
→ Le code source complet peut être trouvé sur
GitHub