代码之家  ›  专栏  ›  技术社区  ›  Riddhi Shah

集合视图自动快速移动到下一个单元格

  •  18
  • Riddhi Shah  · 技术社区  · 9 年前

    我正在尝试创建类似Flipkart的水平滑块。我正在使用水平滚动和分页的collectionView。单元格包含imageView。我成功地手动水平滚动项目,但我希望所有这些项目都能自动和手动移动。我不知道如何自动滚动collectionView的项目。请指导我这样做。

    我在viewDidAppear中使用了此代码:

    let visibleIndexPath: NSIndexPath = self.collectionView.indexPathForCell(cell)!
    
    self.collectionView.scrollToItemAtIndexPath(visibleIndexPath,  
    atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
    

    谢谢

    编辑:

    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)
    
        }
    
    }
    

    这是我的全部代码……我无法进入最后一个单元格后的第一个单元格。请帮帮我。

    12 回复  |  直到 9 年前
        1
  •  23
  •   Babul Prabhakar    9 年前

    下面是您可以尝试的代码:

        /**
         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);
    
    
        }
    
        2
  •  20
  •   Fabian    5 年前

    对于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:-您的收藏视图

    横幅计数:-包含集合视图的单元格数

        3
  •  13
  •   Himanshu Patel Daniel Chernyshev    5 年前

    斯威夫特3

    此测试代码滚动到下一个单元格,并返回到最后一个单元格后的第一项。

    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()
        }
    
        4
  •  7
  •   Kamran    9 年前
    /**
     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);
    }
    
        5
  •  5
  •   Swayambhu    5 年前
    Use your pagecontrol property and scrolltoitem.
    
    func setuptimer() {
      timer = Timer.scheduledTimer(timeInterval: 3, target: self , selector: 
    #selector(startScrolling), userInfo: nil, repeats: true)
    
    }
    
    @objc func startScrolling() {
    
        if pageControl.currentPage == pageControl.numberOfPages - 1 {
            pageControl.currentPage = 0
        } else {
        pageControl.currentPage += 1
        }
        <yourCollectionView>.scrollToItem(at: IndexPath(row: pageControl.currentPage, section: 0), at: .right, animated: true)
    }
    
        6
  •  4
  •   ingconti    7 年前

    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);
        }
    
    }
    
        7
  •  3
  •   Kqtr Markus    3 年前

    这是我稍微改进的解决方案。当用户手动开始滚动时,它会停止滚动,如果再次使用单元格,则会重新启动滚动。

    private var indexCurrentCell = 0
    private weak var timer: Timer?
    
    private var items = [Item]() {
        didSet {
            collectionView.reloadData()
    
            indexCurrentCell()
        }
    }
    
    private func startAutoscrolling() {
        indexCurrentCell = 0
        timer?.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { [weak self] timer in
            guard let self = self else {
                timer.invalidate()
                return
            }
    
            guard !self.items.isEmpty else {
                return
            }
    
            if self.indexCurrentCell < self.items.count {
                let indexPath = IndexPath(item: self.indexCurrentCell, section: 0)
                self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
                self.indexCurrentCell += 1
            } else {
                self.indexCurrentCell = 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()
    
        startAutoscrolling()
    }
    
        8
  •  2
  •   Moinuddin Girach    6 年前

    试试这个

    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);
        }
    }
    
        9
  •  1
  •   Duncan C    8 年前

    我建议使用集合视图方法 scrollToItem(at:at:animated:) 而不是滚动RectToVisible。它可以让您不必计算出要显示的矩形。您只需指定要滚动到的indexPath。

        10
  •  1
  •   Ashutosh Mishra    3 年前

    在Swift 4&在上面,我添加了以下代码,工作得非常好。当我们手动滚动时,计时器已停止,当手动结束滚动时,定时器再次从上次滚动的索引开始。

    将变量初始化为:-

     private var timer: Timer?
     private var indexCurrentCell = 0
    

    然后在类或扩展中添加以下代码,如下所示:-

    func scrollViewWillBeginDragging(scrollView: UIScrollView) {
        self.stopTimer()
    }
    
    func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        self.startTimerForAutoScroll()
    }
    
    private func startTimerForAutoScroll() {
        self.startAutoScroll()
    }
    
    private func stopTimer() {
        timer?.invalidate()
        timer = nil
    }
    
    private func startAutoScroll() {
        indexCurrentCell = 0
        timer?.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { [weak self] timer in
            guard let self = self else {
                timer.invalidate()
                return
            }
            
            guard let offersDataArr = self.offersData, !offersDataArr.isEmpty else {
                return
            }
            
            if self.indexCurrentCell < offersDataArr.count {
                let indexPath = IndexPath(item: self.indexCurrentCell, section: 0)
                self.offersCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
                self.indexCurrentCell += 1
            } else {
                self.indexCurrentCell = 1
                self.offersCollectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .centeredHorizontally, animated: true)
            }
        }
        timer?.fire()
    }
    

    并调用函数(startTimerForAutoScroll),从中集合视图数组设置:-

     override func viewDidLoad() {
        super.viewDidLoad()
          offersCollectionView.delegate = self
          offersCollectionView.dataSource = self
          startTimerForAutoScroll()
    }
    
        11
  •  0
  •   Davender Verma    6 年前
     /**
     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);
    
    }
    
        12
  •  0
  •   Mohan Meruva    4 年前

    你可以用这个 AutoScrollCollectionView cocoapod 在特定间隔内自动滚动

    这与从 自动滚动集合视图 然后打电话 启动自动滚动 方法如下所示

    self.autoScrollCollectionView.startAutoScrolling(withTimeInterval: TimeInterval(exactly: 2.0)!)
    
    self.autoScrollCollectionView.stopAutoScrolling()