问题
I am trying to create horizontal slider like Flipkart. I am using collectionView with Horizontal scrolling and paging. Cell contains imageView. I am succeed in scrolling items horizontally manually, but I want all these items to move automatic and manually both. I am not getting how to scroll items of collectionView automatically. Please guide me to do this.
I have use this code in viewDidAppear:
let visibleIndexPath: NSIndexPath = self.collectionView.indexPathForCell(cell)!
self.collectionView.scrollToItemAtIndexPath(visibleIndexPath,
atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
Thanks.
EDIT:
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)
}
}
This is my whole code.. I am not able to go to first cell after last cell. Please Help me.
回答1:
Below is code you can try :
/**
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:
For 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 :- your collection view
banner.Count:- a number of cells containing a collection view
回答3:
Swift 3
This tested code scrolls to the next cell and returns to first item after the last one.
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:
/**
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:
I suggest using the collection view method scrollToItem(at:at:animated:)
rather than scrollRectToVisible. It saves you from having to do calculations to figure out what rectangle to expose. You can just specify an indexPath to which you want to scroll.
回答6:
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:
try this
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);
}
}
回答8:
Here is my slightly improved solution. It stops the scroll when user manually starts to scroll and restarts it if the cell is reused again.
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()
}
回答9:
/**
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);
}
来源:https://stackoverflow.com/questions/36588933/collectionview-move-to-next-cell-automatically-swift