こんにちは、スクロール画像が表示されるときにUICollectionView
を追加したいPageControl
Horizontal Imageリストコードがあります。pagecontrolセレクターとIBOutlet
を追加しましたが、どのように統合できますか? UICollecitonView
の間。 ?
以下の私のコード。
class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet weak var View : DesignableView!
@IBOutlet var collectionView: UICollectionView!
@IBOutlet var collectionViewLayout: UICollectionViewFlowLayout!
@IBOutlet open weak var pageControl: UIPageControl? {
didSet {
pageControl?.addTarget(self, action: #selector(ViewController.pageChanged(_:)), for: .valueChanged)
}
}
override func viewDidLoad() {
super.viewDidLoad()
pageControl?.numberOfPages = 11
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 11;
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: ImageCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCollectionViewCell", for: indexPath) as! ImageCollectionViewCell
cell.label.text = "Cell \(indexPath.row)"
cell.backgroundImageView.image = UIImage(named: "Parallax \(indexPath.row + 1)")
// Parallax cell setup
cell.parallaxTheImageViewScrollOffset(self.collectionView.contentOffset, scrollDirection: self.collectionViewLayout.scrollDirection)
return cell
}
@IBAction open func pageChanged(_ sender: UIPageControl) {
print(sender.currentPage)
}
// MARK: Delegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return collectionView.bounds.size;
}
// MARK: Scrolling
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Parallax visible cells
for cell: ImageCollectionViewCell in collectionView.visibleCells as! [ImageCollectionViewCell] {
cell.parallaxTheImageViewScrollOffset(self.collectionView.contentOffset, scrollDirection: self.collectionViewLayout.scrollDirection)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
ここでは、水平方向のコレクションビューにページコントロールのページネーションを含む完全なクラスがあります。これは現在、私のアプリケーションの1つで動作しており、正常に動作しています。機能しない場合は、お気軽にお問い合わせください。
まず、ストーリーボードで、次を使用してCollectionViewを設定する必要があります。
レイアウト:フロー
スクロール方向:水平
スクロール可能
ページングが有効
@IBOutlet weak var collectionView: UICollectionView! //img: 77
@IBOutlet weak var pageControl: UIPageControl!
var thisWidth:CGFloat = 0
override func awakeFromNib() {
super.awakeFromNib()
thisWidth = CGFloat(self.frame.width)
collectionView.delegate = self
collectionView.dataSource = self
pageControl.hidesForSinglePage = true
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
self.pageControl.currentPage = indexPath.section
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
thisWidth = CGFloat(self.frame.width)
return CGSize(width: thisWidth, height: self.frame.height)
}
私は受け入れられた答えのファンではありません。時々、willDisplay cell
は、ユーザーの操作に応じて、ページコントロールの間違ったページを返します。
私が使用するもの:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}
これにより、ユーザーがスクロールを終了した後にページが更新され、currentPage
のpageControl
がより正確になります。
UIPageControlの応答性を高めるには、scrollViewDidScroll
を使用し、scrollViewの水平方向の中心に関するオフセットを計算することを好みます。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offSet = scrollView.contentOffset.x
let width = scrollView.frame.width
let horizontalCenter = width / 2
pageControl.currentPage = Int(offSet + horizontalCenter) / Int(width)
}
scrollViewDidEndDecelerating
を待つと、UIPageControl
の更新が遅くなります。より応答性の高いUIが必要な場合は、代わりに scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)
を実装することをお勧めします。
各コレクションビューセクションがページであるSwift 4の例:
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if let collectionView = scrollView as? ScoreCollectionView,
let section = collectionView.indexPathForItem(at: targetContentOffset.pointee)?.section {
self.pageControl.currentPage = section
}
}
ルークの答え は私にとっては良いスタートでしたが、2つの問題がありました:それは頻繁に更新されませんでした(すでに他の回答で指摘されています)が、最も重要なことは、最後のアイテムの正しいページを表示しませんでした私のコレクションビュー(水平方向)と、アイテムがほとんど画面を出ていたときにのみページを切り替えました。
最初の問題では、他の人が述べたように、scrollViewDidScroll
を使用するとより良いエクスペリエンスが提供されました。頻繁に電話をかけることによるパフォーマンスの問題を心配していましたが、何も気付きませんでした。
2番目の問題に関しては、私のユースケースでは、画面の中央にあるセルのindexPathを見つけると、より良い解決策が得られました。ユースケースが画面上の3つ以上のセルに収まる場合は、調整が必要になる場合があることに注意してください。これは、最後のセルが画面の中央に到達しないためです。ただし、その場合はUIPageControl
を使用するのは理想的ではないかもしれないと主張します。
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(Origin: self.collectionView.contentOffset, size: self.collectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = self.collectionView.indexPathForItem(at: visiblePoint) {
self.pageControl.currentPage = visibleIndexPath.row
}
}
Swift 5の非常にスムーズな作業
//MARK:- For Display the page number in page controll of collection view Cell
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(Origin: self.collectionview.contentOffset, size: self.collectionview.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = self.collectionview.indexPathForItem(at: visiblePoint) {
self.pageControl.currentPage = visibleIndexPath.row
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let visibleRect = CGRect(Origin: self.cvImageListing.contentOffset, size: self.cvImageListing.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
if let visibleIndexPath = self.cvImageListing.indexPathForItem(at: visiblePoint) {
self.pageControl.currentPage = visibleIndexPath.row
}
}