web-dev-qa-db-ja.com

UICollectionView画像スクロール内にPageControlを追加する方法

こんにちは、スクロール画像が表示されるときにUICollectionViewを追加したいPageControl Horizo​​ntal 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.
    }



}
22
SwiftDeveloper

ここでは、水平方向のコレクションビューにページコントロールのページネーションを含む完全なクラスがあります。これは現在、私のアプリケーションの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)
}
39
Juan Curti

私は受け入れられた答えのファンではありません。時々、willDisplay cellは、ユーザーの操作に応じて、ページコントロールの間違ったページを返します。

私が使用するもの:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width)
}

これにより、ユーザーがスクロールを終了した後にページが更新され、currentPagepageControlがより正確になります。

84
luke

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)
}
25
David Baez

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
    }
}
11
Chris Chute

ルークの答え は私にとっては良いスタートでしたが、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
    }
}
5
lbarbosa

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
    }
}
4
Shakeel Ahmed
 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
        }
    }
3