web-dev-qa-db-fra.com

CollectionView passe automatiquement à la cellule suivante swift

J'essaie de créer un curseur horizontal comme Flipkart. J'utilise collectionView avec défilement horizontal et pagination. La cellule contient imageView. Je réussis à faire défiler les éléments horizontalement manuellement, mais je veux que tous ces éléments se déplacent automatiquement et manuellement les deux. Je n'arrive pas à faire défiler les éléments de collectionView automatiquement. Veuillez me guider pour ce faire.

J'ai utilisé ce code dans viewDidAppear:

let visibleIndexPath: NSIndexPath = self.collectionView.indexPathForCell(cell)!

self.collectionView.scrollToItemAtIndexPath(visibleIndexPath,  
atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)

Merci.

MODIFIER:

import UIKit

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet var pageControl: UIPageControl!
    @IBOutlet var collectionView: UICollectionView!
    var begin = false
    let image1 = UIImage(named: "Slide 1")
    let image2 = UIImage(named: "Slide 2")
    let image3 = UIImage(named: "Slide 1")

    var images = [UIImage]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        images = [image1!, image2!, image3!]
        startTimer()
    }        

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        pageControl.numberOfPages = images.count
        return images.count
    }

    var cell : CollectionViewCell1!

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

      cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell1", forIndexPath: indexPath) as! CollectionViewCell1
        cell.cell_image.image = images[indexPath.row]

        return cell
    }


    /**
     Scroll to Next Cell
     */
    func scrollToNextCell(){

        //get cell size
        let cellSize = CGSizeMake(self.view.frame.width, self.view.frame.height);

        //get current content Offset of the Collection view
        let contentOffset = collectionView.contentOffset;

            //scroll to next cell
        if begin == true
        {
            pageControl.currentPage == 0
            collectionView.scrollRectToVisible(CGRectZero, animated: true)
            begin = false
        }
        else
        {
            collectionView.scrollRectToVisible(CGRectMake(contentOffset.x + cellSize.width, contentOffset.y, cellSize.width, cellSize.height), animated: true);
        }

    }

    /**
     Invokes Timer to start Automatic Animation with repeat enabled
     */

    func startTimer() {

       NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: #selector(ViewController.scrollToNextCell), userInfo: nil, repeats: true);


    }

    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

        // If the scroll animation ended, update the page control to reflect the current page we are on

        pageControl.currentPage = Int((collectionView.contentOffset.x / collectionView.contentSize.width) * CGFloat(images.count))

        if collectionView.contentSize.width == collectionView.contentOffset.x + self.view.frame.width
        {
            begin = true

        }

    }

    func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {

        // Called when manually setting contentOffset
        scrollViewDidEndDecelerating(scrollView)

    }

}

Ceci est mon code entier .. Je ne peux pas aller à la première cellule après la dernière cellule. Aidez-moi, s'il vous plaît.

9
Riddhi Shah

Voici le code que vous pouvez essayer:

    /**
     Scroll to Next Cell
     */
    func scrollToNextCell(){

        //get Collection View Instance
        let collectionView:UICollectionView;

        //get cell size
        let cellSize = CGSizeMake(self.view.frame.width, self.view.frame.height);

        //get current content Offset of the Collection view
        let contentOffset = collectionView.contentOffset;

        //scroll to next cell
        collectionView.scrollRectToVisible(CGRectMake(contentOffset.x + cellSize.width, contentOffset.y, cellSize.width, cellSize.height), animated: true);


    }

    /**
     Invokes Timer to start Automatic Animation with repeat enabled
     */
    func startTimer() {

        let timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("scrollToNextCell"), userInfo: nil, repeats: true);


    }
9
Babul Prabhakar

Pour Swift4

override func viewDidLoad() {
    super.viewDidLoad()

    startTimer()
}



func startTimer() {

    let timer =  Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.scrollAutomatically), userInfo: nil, repeats: true)
}


@objc func scrollAutomatically(_ timer1: Timer) {

    if let coll  = topMenuCollection {
        for cell in coll.visibleCells {
            let indexPath: IndexPath? = coll.indexPath(for: cell)
            if ((indexPath?.row)! < banner.count - 1){
                let indexPath1: IndexPath?
                indexPath1 = IndexPath.init(row: (indexPath?.row)! + 1, section: (indexPath?.section)!)

                coll.scrollToItem(at: indexPath1!, at: .right, animated: true)
            }
            else{
                let indexPath1: IndexPath?
                indexPath1 = IndexPath.init(row: 0, section: (indexPath?.section)!)
                coll.scrollToItem(at: indexPath1!, at: .left, animated: true)
            }

        }
    }
}

topMenuCollection: - votre vue de collection

banner.Count: - un certain nombre de cellules contenant une vue de collection

10
Sameer Saif

Swift

Ce code testé défile jusqu'à la cellule suivante et revient au premier élément après le dernier.

     func setTimer() {
        let _ = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(MainVC.autoScroll), userInfo: nil, repeats: true)
    }

    var x = 1

    @objc func autoScroll() {
        if self.x < self.storiesForCollectionView.count {
        let indexPath = IndexPath(item: x, section: 0)
        self.collectionViewUp.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
        self.x = self.x + 1
        } else {
            self.x = 0
            self.collectionViewUp.scrollToItem(at: IndexPath(item: 0, section: 0), at: .centeredHorizontally, animated: true)
        }
    }
override func viewDidLoad() {
        super.viewDidLoad()
        setTimer()
    }
8
Daniel Chernyshev
/**
 Scroll to Next Cell
 */
func scrollToNextCell(){

    //get cell size
    let cellSize = CGSizeMake(self.view.frame.width, self.view.frame.height);

    //get current content Offset of the Collection view
    let contentOffset = collectionView.contentOffset;

    if collectionView.contentSize.width <= collectionView.contentOffset.x + cellSize.width
    {
        collectionView.scrollRectToVisible(CGRectMake(0, contentOffset.y, cellSize.width, cellSize.height), animated: true);

    } else {
        collectionView.scrollRectToVisible(CGRectMake(contentOffset.x + cellSize.width, contentOffset.y, cellSize.width, cellSize.height), animated: true);

    }

}

/**
 Invokes Timer to start Automatic Animation with repeat enabled
 */
func startTimer() {
    NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("scrollToNextCell"), userInfo: nil, repeats: true);
}
7
Kamran

Voici ma solution légèrement améliorée. Il arrête le défilement lorsque l'utilisateur commence manuellement à le faire défiler et le redémarre si la cellule est réutilisée à nouveau.

var x = 0
weak var timer: Timer?

var cashbackOffers = [CashbackOffer]() {
    didSet {
        collectionView.reloadData()
        autoScroll()
    }
}

fileprivate func autoScroll() {
    x = 0
    timer?.invalidate()
    timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { [weak self] timer in
        guard let `self` = self else {
            timer.invalidate()
            return
        }
        if self.cashbackOffers.count == 0 {
            return
        }
        if self.x < self.cashbackOffers.count {
            let indexPath = IndexPath(item: self.x, section: 0)
            self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
            self.x = self.x + 1
        } else {
            self.x = 1
            self.collectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .centeredHorizontally, animated: true)
        }
    }
    timer?.fire()
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if scrollView.isTracking {
        timer?.invalidate()
    }
}

override func awakeFromNib() {
    super.awakeFromNib()
    autoScroll()
}
1
Ankit Srivastava

essaye ça

var index = 0
var inForwardDirection = true
var timer: Timer?

@objc func scrollToNextCell() {

    //scroll to next cell
    let items = collectionViewTable.numberOfItems(inSection: 0)
    if (items - 1) == index {
        collectionViewTable.scrollToItem(at: IndexPath(row: index, section: 0), at: UICollectionViewScrollPosition.right, animated: true)
    } else if index == 0 {
        collectionViewTable.scrollToItem(at: IndexPath(row: index, section: 0), at: UICollectionViewScrollPosition.left, animated: true)
    } else {
        collectionViewTable.scrollToItem(at: IndexPath(row: index, section: 0), at: UICollectionViewScrollPosition.centeredHorizontally, animated: true)
    }

    if inForwardDirection {
        if index == (items - 1) {
            index -= 1
            inForwardDirection = false
        } else {
            index += 1
        }
    } else {
        if index == 0 {
            index += 1
            inForwardDirection = true
        } else {
            index -= 1
        }
    }

}

/**
 call this method when collection view loaded
 */
func startTimer() {
    if timer == nil {
        timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(scrollToNextCell), userInfo: nil, repeats: true);
    }
}
1
Moinuddin Girach

Je suggère d'utiliser la méthode de vue de collection scrollToItem(at:at:animated:) plutôt que scrollRectToVisible. Cela vous évite d'avoir à faire des calculs pour déterminer le rectangle à exposer. Vous pouvez simplement spécifier un indexPath auquel vous souhaitez faire défiler.

1
Duncan C

Swift 4:

func scrollToNextCell(){

    //get cell size
    let cellSize = view.frame.size

    //get current content Offset of the Collection view
    let contentOffset = collectionView.contentOffset

    if collectionView.contentSize.width <= collectionView.contentOffset.x + cellSize.width
    {
        let r = CGRect(x: 0, y: contentOffset.y, width: cellSize.width, height: cellSize.height)
        collectionView.scrollRectToVisible(r, animated: true)

    } else {
        let r = CGRect(x: contentOffset.x + cellSize.width, y: contentOffset.y, width: cellSize.width, height: cellSize.height)
        collectionView.scrollRectToVisible(r, animated: true);
    }

}
1
ingconti
 /**
 Scroll to Next Cell
 */
@objc func scrollToNextCell(){



    //get cell size
    let cellSize = CGSize(width:self.view.frame.size.width, height:viewForCV.frame.size.height)


    //get current content Offset of the Collection view
    let contentOffset = cvAdvertisements.contentOffset;

    if cvAdvertisements.contentSize.width <= cvAdvertisements.contentOffset.x + cellSize.width
    {
        cvAdvertisements.scrollRectToVisible(CGRect(x:0, y:contentOffset.y, width:cellSize.width, height:cellSize.height), animated: true);

    } else {

        cvAdvertisements.scrollRectToVisible(CGRect(x:contentOffset.x + cellSize.width, y:contentOffset.y, width:cellSize.width, height:cellSize.height), animated: true);

    }

}

/**
 Invokes Timer to start Automatic Animation with repeat enabled
 */
func startTimer() {

    Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(LoginViewController.scrollToNextCell), userInfo: nil, repeats: true);

}
0
Davender Verma