{"id":23825,"date":"2015-07-27T01:03:04","date_gmt":"2015-07-26T19:33:04","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=23825"},"modified":"2016-12-15T15:29:19","modified_gmt":"2016-12-15T09:59:19","slug":"infinite-scrolling-using-uicollectionview-in-swift","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/infinite-scrolling-using-uicollectionview-in-swift\/","title":{"rendered":"Infinite Scrolling using UICollectionView in Swift"},"content":{"rendered":"<h2>Introduction<\/h2>\n<div>This tutorial is for <a title=\"ios app development services\" href=\"http:\/\/www.tothenew.com\/mobile-ios-application-development-services\">iOS application<\/a> developers to insert\u00a0infinite scrolling in swift to achieve gallery effect using UICollectionView (Objective-C class). We will use UIScrollView delegate methods, UICollectionView &amp; custom UICollectionViewCell for endless scrolling. You can add more items in collection view data source by adding images (.png) files in resource folder or can use web services to get data at run-time. Here we will play with UIScrollView delegate methods. We don&#8217;t need to add UIScrollView because UICollectionView is a subclass of UIScrollView.<br \/>\n<b>Inheritance: <\/b>NSObject-&gt;UIResponder-&gt;UIView-&gt;UIScrollView-&gt;UICollectionView.<\/div>\n<p>&nbsp;<\/p>\n<h2>Infinite Scrolling Using Collection View Demo Video<\/h2>\n<p><iframe loading=\"lazy\" width=\"625\" height=\"469\" src=\"https:\/\/www.youtube.com\/embed\/ICOWzFsWqe4?feature=oembed\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<div>In this sample video you can see how image gallery can be implemented in iPhone using horizontal scrolling.<\/div>\n<p>&nbsp;<\/p>\n<h2>Getting Started<\/h2>\n<div>First create a new project iOS\\Application\\Single View Application template, click next. Enter &#8220;Infinite Scrolling&#8221; for the Product Name, Language &#8220;Swift&#8221;, Device &#8220;iPhone&#8221;, Core Data not checked and click next.<\/div>\n<div>Then download the <a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/07\/InfiniteScrollingResources.zip\">resource pack<\/a> for this project e.i. images (.png) and store them in a &#8220;resource&#8221; folder or image assets.<\/div>\n<div><\/div>\n<div>\n<h2>Infinite (Endless) Scrolling Source Code<\/h2>\n<div>Add Infinite Scrolling View Controller class to your project. To do this, go to\u00a0File\\New\\File\u00a0and select\u00a0iOS\\Source\\Swift File. Name the file\u00a0InfiniteScrollingViewController.swift, and click\u00a0Create.<\/div>\n<div><\/div>\n<div>\n<h2>Creating your Views<\/h2>\n<\/div>\n<div>UICollectionView: Drag a UICollectionView into your ViewController from Object library. If you have basic knowledge of Autolayout then you can add constraints on collection view.<\/div>\n<div>So far you have added views for you project.\u00a0Open\u00a0InfiniteScrollingViewController.swift.\u00a0\u00a0You will see that the class has the following code in it already:<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>import UIKit\r\n\u00a0\r\nclass ViewController: UIViewController {\r\n\u00a0\r\n  override func viewDidLoad() {\r\n    super.viewDidLoad()\r\n    \/\/ Do any additional setup after loading the view, typically from a nib.\r\n  }\r\n\r\n  override func didReceiveMemoryWarning() {\r\n    super.didReceiveMemoryWarning()\r\n    \/\/ Dispose of any resources that can be recreated.\r\n  }\r\n\u00a0\r\n}<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2>Adding Properties to your InfiniteScrolling View Controller<\/h2>\n<\/div>\n<div>To do this, add these following properties to &#8220;InfiniteScrollingViewController&#8221; (right before viewDidLoad):<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>@IBOutlet weak var infiniteScrollingCollectionView: UICollectionView!\r\nprivate let reuseIdentifier = \"InfiniteScrollingCell\"\r\nprivate var photosUrlArray = [String]()\r\nlet WINDOW_WIDTH = UIScreen.mainScreen().bounds.width\r\nlet WINDOW_HEIGHT = UIScreen.mainScreen().bounds.height\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>Add the following in the ViewDidLoad:<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>self.title = \"Infinite Scrolling\"\r\nself.automaticallyAdjustsScrollViewInsets = false\r\nphotosUrlArray = [\"A_Photographer.jpg\",\"A_Song_of_Ice_and_Fire.jpg\",\"Another_Rockaway_Sunset.jpg\",\"Antelope_Butte.jpg\"]\r\ninfiniteScrollingCollectionView?.delegate = self\r\ninfiniteScrollingCollectionView?.dataSource = self\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3>UICollectionViewDataSource<\/h3>\n<div>Let\u2019s start with the data source. In InfiniteScrollingViewController.swift add an extension with the following data-source methods:<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>#pragma mark - UICollectionView Datasource\r\nextension InfiniteScrollingViewController : UICollectionViewDataSource{\r\n func numberOfSectionsInCollectionView(collectionView: UICollectionView) -&gt; Int {\r\n        return 1\r\n    }\r\n    \r\n    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -&gt; Int {\r\n        return photosUrlArray.count\r\n    }\r\n    \r\n    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -&gt; UICollectionViewCell {\r\n        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! InfiniteScrollingCell\r\n        let photoName = photoForIndexPath(indexPath)\r\n        \r\n        cell.configureCell(photoName)\r\n        \r\n        return cell\r\n    }\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3>UICollectionView Flow Layout Delegate Methods<\/h3>\n<div>In InfiniteScrollingViewController.swift, add an extension with the following delegate methods. Here we multiply collection view item&#8217;s height by 1.00346 to achieve aspect ration for images.<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>#pragma mark - UICollectionView Flow Layout Delegate\r\nextension InfiniteScrollingViewController : UICollectionViewDelegateFlowLayout {\r\nfunc collectionView(collectionView: UICollectionView,\r\n        layout collectionViewLayout: UICollectionViewLayout,\r\n        sizeForItemAtIndexPath indexPath: NSIndexPath) -&gt; CGSize {\r\n            \r\n            let size:CGSize = CGSizeMake(WINDOW_WIDTH, (WINDOW_WIDTH)*1.203460)\r\n            return size\r\n            \r\n    }\r\n    \r\n    func collectionView(collectionView: UICollectionView,\r\n        layout collectionViewLayout: UICollectionViewLayout,\r\n        insetForSectionAtIndex section: Int) -&gt; UIEdgeInsets {\r\n            return UIEdgeInsetsMake(0, 0, 0, 0)\r\n    }\r\n\r\n}<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<div>Now before you run your project add custom collection view cell.<\/div>\n<h3>Adding custom collection view cell<\/h3>\n<div>Go to File\\New\\File and select iOS\\Source\\Swift File. Name the file InfiniteScrollingCell.swift, and click Create with xib.<br \/>\nOpen the Xib file and drag the UIImageView from the object library.<\/div>\n<h3>Adding Properties to your InfiniteScrolling Collection View cell<\/h3>\n<div>To do this, add these following properties to &#8220;InfiniteScrollingCell.swift&#8221; (right before awakeFromNib):<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>@IBOutlet weak var imageView: UIImageView!\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3>Configure collection view cell<\/h3>\n<div>Add the following at the end your collection view cell class:<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>func configureCell(photoName:String){\r\nimageView?.image = UIImage(named: photoName)\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2>Adding endless scrolling logic here<\/h2>\n<div>Concept of endless scrolling is &#8220;Rotate an array by k elements&#8221;. To understand code in detail. Open the &#8220;InfiniteScrollingViewController.swift&#8221; and at the end of class add the following methods:<\/div>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>func photoForIndexPath(indexPath: NSIndexPath) -&gt; String {\r\n        return photosUrlArray[indexPath.row]\r\n    }\r\n    \r\n    \r\n    func reversePhotoArray(photoArray:[String], startIndex:Int, endIndex:Int){\r\n        if startIndex &gt;= endIndex{\r\n            return\r\n        }\r\n        swap(&amp;photosUrlArray[startIndex], &amp;photosUrlArray[endIndex])\r\n        \r\n        reversePhotoArray(photosUrlArray, startIndex: startIndex + 1, endIndex: endIndex - 1)\r\n    }<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3>UIScrollView Delegate Methods<\/h3>\n<div>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>#pragma mark - UIScrollView Delegate\r\nextension InfiniteScrollingViewController:UIScrollViewDelegate{\r\n\r\n   func scrollViewDidEndDecelerating(scrollView: UIScrollView) {\r\n        \/\/ Calculate where the collection view should be at the right-hand end item\r\n      let fullyScrolledContentOffset:CGFloat = infiniteScrollingCollectionView.frame.size.width * CGFloat(photosUrlArray.count - 1)\r\n      if (scrollView.contentOffset.x &gt;= fullyScrolledContentOffset) {\r\n            \r\n      \/\/ user is scrolling to the right from the last item to the 'fake' item 1.\r\n      \/\/ reposition offset to show the 'real' item 1 at the left-hand end of the collection view\r\n       if photosUrlArray.count&gt;2{  \r\n         reversePhotoArray(photosUrlArray, startIndex: 0, endIndex: photosUrlArray.count - 1)\r\n         reversePhotoArray(photosUrlArray, startIndex: 0, endIndex: 1)\r\n         reversePhotoArray(photosUrlArray, startIndex: 2, endIndex: photosUrlArray.count - 1)\r\n         var indexPath : NSIndexPath = NSIndexPath(forRow: 1, inSection: 0)               infiniteScrollingCollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .Left, animated: false)\r\n            }\r\n      }\r\n      else if (scrollView.contentOffset.x == 0){\r\n            \r\n       if photosUrlArray.count&gt;2{\r\n        reversePhotoArray(photosUrlArray, startIndex: 0, endIndex: photosUrlArray.count - 1)\r\n        reversePhotoArray(photosUrlArray, startIndex: 0, endIndex: photosUrlArray.count - 3)\r\n        reversePhotoArray(photosUrlArray, startIndex: photosUrlArray.count - 2, endIndex: photosUrlArray.count - 1)\r\n        var indexPath : NSIndexPath = NSIndexPath(forRow: photosUrlArray.count - 2, inSection: 0)\r\n              infiniteScrollingCollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: .Left, animated: false)\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2>You can download the completed project from\u00a0<a href=\"\/blog\/wp-ttn-blog\/uploads\/2015\/07\/InfiniteScrollingCollectionView.zip\">here<\/a>.<\/h2>\n<div><\/div>\n<div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introduction This tutorial is for iOS application developers to insert\u00a0infinite scrolling in swift to achieve gallery effect using UICollectionView (Objective-C class). We will use UIScrollView delegate methods, UICollectionView &amp; custom UICollectionViewCell for endless scrolling. You can add more items in collection view data source by adding images (.png) files in resource folder or can use [&hellip;]<\/p>\n","protected":false},"author":169,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":300},"categories":[1400,1],"tags":[4289,4291,4848,4290],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/23825"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/169"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=23825"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/23825\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=23825"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=23825"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=23825"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}