iosswiftuicollectionviewcarouseluipagecontrol

Swift. Problem with automatically scrolling Carousel in CollectionView


I have a problem with automatically scrolling Carousel in CollectionView.

Interval 5 sec, and when First scroll go, instead of it must be slide to the next Image, it scroll to 16 points right, to the edge of the screen. But then it goes as it should.

What I'm missing ?

My code is:

class ViewController: UIViewController {
        
    private var topChannelsCollectionView = TopChannelsCollectionView()
        
    @IBOutlet var dots: UIPageControl!
    
    var timer = Timer()
    var counter = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        dots.numberOfPages = TopChannelModel.fetchChannels().count
        dots.currentPage = 0
        
        DispatchQueue.main.async { [self] in
            timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(automaticScrollImage), userInfo: nil, repeats: true)
        }
        
        view.addSubview(topChannelsCollectionView)
       
        topChannelsCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        topChannelsCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        topChannelsCollectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 6).isActive = true
        topChannelsCollectionView.heightAnchor.constraint(equalToConstant: 200).isActive = true
        
        topChannelsCollectionView.setContentFor(channels: TopChannelModel.fetchChannels())
        
        // MARK: - add constraints for dots
        dots.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        dots.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        dots.topAnchor.constraint(equalTo: topChannelsCollectionView.bottomAnchor, constant: 10).isActive = true
        dots.widthAnchor.constraint(equalToConstant: 200).isActive = true
        
        dots.translatesAutoresizingMaskIntoConstraints = false
    }
    
    @objc func automaticScrollImage() {
        
        if counter < dots.numberOfPages {
            let index = IndexPath.init(item: counter, section: 0)
            self.topChannelsCollectionView.scrollToItem(at: index, at: .centeredHorizontally, animated: true)
            dots.currentPage = counter
            counter += 1
        } else {
            counter = 0
            let index = IndexPath.init(item: counter, section: 0)
            self.topChannelsCollectionView.scrollToItem(at: index, at: .centeredHorizontally, animated: false)
            dots.currentPage = counter
            counter = 1
        }
        
    }

}

Code from TopChannelsCollectionView.swift:

class TopChannelsCollectionView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource {

private var channels: [TopChannelModel] = []

init() {
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .horizontal
    super.init(frame: .zero, collectionViewLayout: layout)
    
    backgroundColor = #colorLiteral(red: 0.113761507, green: 0.1048973277, blue: 0.150441885, alpha: 1)
    delegate = self
    dataSource = self
    register(TopChannelsCollectionViewCell.self, forCellWithReuseIdentifier: TopChannelsCollectionViewCell.reuseId)
    
    translatesAutoresizingMaskIntoConstraints = false
    
    // за расстояние между ячейками у нас отвечает layout, свойство minimumLineSpacing
    layout.minimumLineSpacing = Constants.galleryMinimumLineSpacing
    
    // и св-во CollectionView, которое отвечает за принятие отступов
    contentInset = UIEdgeInsets(top: 0, left: Constants.leftDistanceToView, bottom: 0, right: Constants.rightDistanceToView)
    
    showsHorizontalScrollIndicator = false
    showsVerticalScrollIndicator = false
    isPagingEnabled = true
}

Solution

  • I Solved it !!! Fuch!

    Problem was in func automatic scrolling !

    I write this counter:

    @objc func automaticScrollImage() {
        
        if counter < dots.numberOfPages - 1 {
            counter += 1
        } else {
            counter = 0
        }
        
        self.topChannelsCollectionView.scrollToItem(at: IndexPath(item: counter, section: 0), at: .centeredHorizontally, animated: true)
        dots.currentPage = counter
        
    }