MILCarouselCollectionView is an easy to use, drop-in, reusable UI component built in Swift to display collection view cells in a scrollable paged circular carousel. The collection view has the ability to be scrolled by the user or automatically scroll on its own every 4 seconds. As well It can be customized to handle and display any type of data after some minor changes (explained below). By default, the collection view is writen to display images in each cell. MILCarouselCollectionView has the ability to display local images stored in the xcode project as well as has the ability to asynchronously download and cache images from image URLs using its built in functionality or using third party framework [SDWebImage](https://github.com/rs/SDWebImage). In addition, MILCarouselCollectionView also supports displaying placeholder cells while it waits to receive data from a server and resolve a URL to an image.
Simply copy the MILCarouselCollectionView
folder into your Xcode project. This folder contains the following 4 files:
MILCarouselCollectionViewController.swift
MILCarouselCollectionViewFlowLayout.swift
MILCarouselCollectionViewCell.swift
MILCarouselCollectionViewCell.xib
## Adding a MILCarouselCollectionViewContoller to a UIViewController
For both storyboard and programmatic implementations, you can reference the ViewController.swift
file in the example xcode project to see an example in context.
### Programmatic Implementation
-
In the UIViewController class file you would like to add a programmatic MILCarouselCollectionViewController to, create a property at the top of the file:
var programmaticCarouselCollectionViewController : MILCarouselCollectionViewController!
1. To initialize an instance of MILCarouselCollectionViewController programmatically and set it the UIViewController's `programmaticCarouselCollectionViewController` property we do:
```swift
let flow = MILCarouselCollectionViewFlowLayout()
self.programmaticCarouselCollectionViewController = MILCarouselCollectionViewController(collectionViewLayout: flow)
-
To set the frame of the MILCarouselCollectionViewController's view we do:
self.programmaticCarouselCollectionViewController.view.frame = CGRectMake(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat)
1. To add the MILCarouselCollectionViewController's view to the UIViewController's view we do:
```swift
self.addChildViewController(self.programmaticCarouselCollectionViewController)
self.programmaticCarouselCollectionViewController.didMoveToParentViewController(self)
self.view.addSubview(self.programmaticCarouselCollectionViewController.view)
### Storyboard Implementation
-
On the UIViewController you would like to add the MILCarouselCollectionView to, add a
Container View
to UIViewController's view and delete the new UIViewController storyboard auto embeded in the container view. Add the appropriate autolayout constraints to the container view so that it displays to your liking within the UIViewController's view. The height and width you make the container view will define the height and width of the MILCarouselCollectionView as well as the height and width of the MILCarouselCollectionViewCells in the MILCarouselCollectionView. Your storyboard should now look like this: -
Next add a
UICollectionViewController
to the storyboard. Select this UICollectionViewController on storyboard so that it's highlighted and then select theIdentity Inspector
of theUtilies
sidebar. Under "Custom Class" make the UICollectionViewController a subclass ofMILCarouselCollectionViewController
-
Hold down the control key while you click and drag from the container view on the UIViewController to the UICollectionViewController (now a MILCarouselCollectionViewController). A dialog box will show asking you what kind of segue you would like to choose, select
Your storyboard should now look like this:Embed
. -
Select the segue arrow that was just added that goes from the container view to the MILCarouselCollectionViewController. In the
Attributes Inspector
change theStoryboard Embed Segue Identifier
tocarouselCollectionView
. -
Go to the swift file that represents the UIViewController that has the container view you added. Create a property at the top of the file
var storyboardCarouselCollectionViewController : MILCarouselCollectionViewController!
-
Add a prepare for segue method to your UIViewController if it isn't already added and add the following lines to get the instance of the
MILCarouselCollectionViewController
you added on the storyboard and to save this instance to the UIViewController'sstoryboardCarouselCollectionViewController
propertyoverride func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if(segue.identifier == "carouselCollectionView"){ self.storyboardCarouselCollectionViewController = segue.destinationViewController as! MILCarouselCollectionViewController } }
## Usage
###Set Placeholder Cell Image
A placeholder cell is a cell that is displayed in the MILCarouselCollectionView while the MILCarouselCollectionViewController waits to be passed data from its parent view controller, this can be useful if there is a delay while retrieving data from a server call. By default, it will display one placeholder cell that it will scroll back and forth to. When a MILCarouselCollectionViewController finally receives an array of data, a placeholder image is displayed in each cell of the MILCarouselCollectionView while we wait for a cell to resolve a url to an image. The following code snippets can be used after you init a MILCarouselCollectionViewController programmatically, or once you get reference to the storyboard MILCarouselCollectionViewController in the prepareForSegue method. (Examples shown in the example project). It should be noted that the following code snippet should be called before we pass data to the MILCarouselCollectionViewController.
To set the placeholder item image to a locally stored image within the Xcode project, we pass it the name:
self.storyboardCarouselCollectionViewController.localPlaceHolderImageName = "image_name"
###Passing Data to the MILCarouselCollectionView
By default, a MILCarouselCollectionViewControler expects to handle an array of strings that represent a URL with its built in asychronous image url downloading and caching mechanisms. However, it should be noted that it also supports handling image url strings using the SDWebImage framework. In addition, a MILCarouselCollectionViewController can handle an array of strings that represent names of locally stored images in the Xcode project.
Chances are when you try to resolve image URL's to images you will get the following warning and you won't be able to download the images:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
Error: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
To fix this, go to your info.plist
file and add the following:
<key>NSAppTransportSecurity</key>
<dict>
<!--Include to allow all connections-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
This of course is the lazy way to fix the problem. Eventually you would want to specify which specific web domains you want the app to accept. For more information about this try this article
-
To pass an array of
image url strings
to a MILCarouselCollectionViewController and have it handle this using its built in asychronous image url downloading and caching we can do:self.carouselCollectionViewController.setToHandleImageURLStrings() let imageURLArray = [String]() //populate this array with url strings //pass array of strings that represent URLs of images self.carouselCollectionViewController.refresh(imageURLArray)
- To pass an array of `image url strings` to a MILCarouselCollectionViewController and have it handle this using the **[SDWebImage](https://github.com/rs/SDWebImage)** framework we can do:
``` swift
self.carouselCollectionViewController.setToHandleImageURLStringsUsingSDWebImage()
let imageURLArray = [String]()
//populate this array with url strings
//pass array of strings that represent URLs of images
self.carouselCollectionViewController.refresh(imageURLArray)
```
Note that in order to use SDWebImage, you must import SDWebImage into your xcode project yourself. As well you will need to uncomment the code in the `setUpCellWithImageURLUsingSDWebImage` method in the `MILCarouselCollectionViewController.swift` file shown below:
```swift
private func setUpCellWithImageURLUsingSDWebImage(cell : MILCarouselCollectionViewCell, indexPath : NSIndexPath) -> MILCarouselCollectionViewCell {
//Code commented out since SDWebImage isn't imported in the project and to surpress errors and warnings, uncomment to use with sdWebImage
/*
let urlString = self.dataArray[indexPath.row]
let url = NSURL(string: urlString)
cell.imageView.sd_setImageWithURL(url, placeholderImage: UIImage(named: self.localPlaceHolderImageName))
*/
return cell
}
<br>
- To pass an array of `strings that represent locally stored images` to a MILCarouselCollectionViewController we can do:
```swift
self.carouselCollectionViewController.setToHandleLocalImageNameStrings()
let imageNameArray = [String]()
//populate this array with locally stored image names
//pass array of strings that represent names of locally stored images
self.carouselCollectionViewController.refresh(imageNameArray)
```
<br>
## Customizing MILCarouselCollectionView
###Changing the Height and Width of the MILCarouselCollectionViewCells
- The `height` and `width` of a MILCarouselCollectionViewCell changes with respect to the MILCarouselCollectionViewController's view height and width.
- If you are dealing with a programmatic implementation of the MILCarouselCollectionViewController, know that when you set the frame of the MILCarouselCollectionViewController, this will also be the height and width of each cell in the MILCarouselCollectionView
- If you are dealing with a storyboard implementation of the MILCarouselCollectionViewController, changing the height and width of the container view that holds the MILCarouselCollectionViewController will also set the height and width of each cell in the MILCarouselCollectionView
<br>
###Changing the Autoscroll Timer Duration
By default, the MILCarouselCollectionView autoscrolls to a new cell every 4 seconds. Whenever the user touches the MILCarouselCollectionView, the autoscroll timer is reset.
To change the duration of the autoscroll timer you can do the following after you initialize a MILCarouselCollectionViewController, but before you pass it data:
```swift
self.carouselCollectionViewController.setAutoScrollTimerDuration(n)
###Disable Autoscrolling
By default, the MILCarouselCollectionView autoscrolls every 4 seconds to a new cell.
To disable autoscrolling, do the following after you intialize a MILCarouselCollectionViewController, but before you pass it data:
self.carouselCollectionViewController.disableAutoScrolling()
###Disable Circular Scrolling By default, when the MILCarouselCollectionView is at the last cell in the collection view, if you scroll past this cell, it will scroll back to the first cell in the collection view.
To disable circular scrolling, do the following after you initialize a MILCarouselCollectionViewController, but before you pass it data:
self.carouselCollectionViewController.disableCircularScrolling()
###Changing the Kind of Data a MILCarouselCollectionViewController Can Handle
To change the kind of data a MILCarouselCollectionViewController can handle, first you will need to modify the dataArray
property in the MILCarouselCollectionViewController.swift
file to be an array of different data types:
var dataArray : [MyDataObject] = []
As well you will need to change the way the MILCarouselCollectionViewController prepares the MILCarouselCollectionViewCell in the cellForItemAtIndexPath method:
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("carouselcell", forIndexPath: indexPath) as! MILCarouselCollectionViewCell
//set up cell with a method that sets up the cell with a custom data object
return self.setUpCellWithCustomDataObject(cell, indexPath: indexPath)
}
###Changing the MILCarouselCollectionViewCell's UI
To change the UI of the MILCarouselCollectionViewCell, you can do this by modifying the MILCarouselCollectionViewCell.xib
file. By default, the collection view cell only has an image view that stretches accross the whole cell. Of course, with modifying the MILCarouselCollectionViewCell's UI, comes changing the way we prepare and set up the data in the cell using the cellForItemAtIndexPath method.
## Requirements * MILCarouselCollectionView has only been tested to work with iOS 9+ and Xcode 7.1.1
Created by Alex Buck at the IBM Mobile Innovation Lab
MILCarouselCollectionView is available under the Apache 2.0 license. See the LICENSE file for more info.
The MILCarouselCollectionViewExample sample application is available under the Apple SDK Sample Code License. Details in the file called SAMPLE_APP_LICENSE
under the Example directory.