4

I've been trying to create an autoscrolling, looping image collection view similar to what you see in the Instagram app on their Search page or the Apple App Store app on their Featured page.

I've been able to do one or the other, but if I have autoscrolling on and the user interacts with the image carousel, it starts jumping around all over the place.

I'd appreciate your thoughts on what I might be doing wrong or what I could do to improve my code.

I currently have a mainCollectionView with another eventsCollectionView nested in the first cell of the maincollectionView. This way I can scroll the whole thing vertically, but can have the first cell scroll horizontally to show the different events.

I found this great tutorial (in Obj-C) on how to make my collection view be an infinite loop: http://adoptioncurve.net/archives/2013/07/building-a-circular-gallery-with-a-uicollectionview/

I am leaving out the cellForItemAtIndexPath and sizeForItemAtIndexPath because the set up of the collectionviews is working just fine. Here is some of the pertinent code for the infinite looping:

var eventImages = ["event1", "event2", "event3", "event4"]
var newEventImages = [String]()

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    newEventImages = eventImages
    var firstItem = eventImages[0]
    var lastItem = eventImages[self.eventImages.count - 1]
    newEventImages.insert(lastItem, atIndex: 0)
    newEventImages.append(firstItem)

    if collectionView == mainCollectionView {
        return array.count + 2
    } else if collectionView == eventsCollectionView {
        return self.newEventImages.count
    } else {
        return 1
    }

}

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
    var offsetMultiplier = CGFloat(self.newEventImages.count - 1)
    var contentOffsetWhenFullyScrolledRight = self.eventsCollectionView.frame.size.width * offsetMultiplier

    if (scrollView.contentOffset.x == contentOffsetWhenFullyScrolledRight) {
        var newIndexPath: NSIndexPath = NSIndexPath(forItem: 1, inSection: 0)
        self.eventsCollectionView.scrollToItemAtIndexPath(newIndexPath, atScrollPosition: UICollectionViewScrollPosition.Left, animated: false)
    } else if (scrollView.contentOffset.x == 0) {
        var newIndexPath: NSIndexPath = NSIndexPath(forItem: (self.newEventImages.count - 2), inSection: 0)
        self.eventsCollectionView.scrollToItemAtIndexPath(newIndexPath, atScrollPosition: UICollectionViewScrollPosition.Left, animated: false)
    }
}

// This function is called in ViewDidAppear
func setFirstScrollImage(collection: UICollectionView) {
    var newIndexPath: NSIndexPath = NSIndexPath(forItem: 1, inSection: 0)
    collection.scrollToItemAtIndexPath(newIndexPath, atScrollPosition: UICollectionViewScrollPosition.Left, animated: false)
}

For the autoscroll, I'm using a delay in the cellForItemAtIndexPath section:

let delay = 4.0 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue()) {
     self.currentEventCell = indexPath.row
     var newIndexPath: NSIndexPath = NSIndexPath(forItem: self.currentEventCell + 1, inSection: 0)
     self.eventsCollectionView.scrollToItemAtIndexPath(newIndexPath, atScrollPosition: UICollectionViewScrollPosition.Left, animated: true)
 }

These two methods seem to work well independently from each other, however, when combined, the auotscroll starts skipping cells and moves erratically as soon as the user swipes.

All ideas are welcome. Let me know what you think. Thank you.

Nate Witty
  • 103
  • 1
  • 7

0 Answers0