INSPhotoGallery — modern looking photo gallery written in Swift for iOS

Michał Zaborowski
inspace labs
Published in
3 min readApr 5, 2016

INSPhotoGallery is a modern looking photo gallery written in Swift for iOS. It can handle downloading of photos but in addition to that it allows you to make custom logic for downloading images, also it allows you to make custom overlay if you won’t like current design. Also it supports interactive flick to dismiss, animated zooming presentation and many more. It was inspired by NYTPhotoViewer.

INSPhotoGallery is using standard UIKit components. It is build on UIPageViewController for swiping between photos, and UIScrollView for image zooming. In addition to that it support custom overlay view by implementing INSPhotosOverlayViewable protocol.

The reason why we wrote this library, is that there is no well written lightweight alternative photo gallery in Swift, which allows you to customize and manage downloading images using custom code.

Usage

The usage is very simple and comes down to a few lines. To present gallery you can use build-in INSPhoto class which implements INSPhotoViewable protocol and supports downloading images from NSURL using NSURLSession. Optionally you can implement INSPhotoViewable to your custom class and then present it.

lazy var photos: [INSPhotoViewable] = {
return [
INSPhoto(imageURL: ..., thumbnailImage: ...),
INSPhoto(imageURL: ..., thumbnailImage: ...)
]
}()

In this case I will be presenting gallery after clicking on the cell, and I will use animated zoom animation. Addition to that Iwill pass all photos to allow user to swipe and switch between them. Using build-in handlers it is very easy to do it, all you need to do is pass initial referenceView and for dismissing view controller you need to implement referenceViewForPhotoWhenDismissingHandler to point a view where animation will end.

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {   let cell = collectionView.cellForItemAtIndexPath(indexPath) as! ExampleCollectionViewCell
let currentPhoto = photos[indexPath.row]
let galleryPreview = INSPhotosViewController(photos: photos, initialPhoto: currentPhoto, referenceView: cell)
galleryPreview.referenceViewForPhotoWhenDismissingHandler = { [weak self] photo in if let index = self?.photos.indexOf({$0 === photo}) {
let indexPath = NSIndexPath(forItem: index, inSection: 0)
return collectionView.cellForItemAtIndexPath(indexPath) as? ExampleCollectionViewCell
}
return nil
}
presentViewController(galleryPreview, animated: true, completion: nil)
}

Custom Photo Model

Let assume the case where you have your own CustomPhoto model and you won’t use build-in type INSPhoto, but pass array of your photo objects directly to gallery. One of the reason why you would like to do this is that you would like use some library for downloading and caching photos or you have NSManagedObject model subclass and you would like to fetch images from database rather that downloading from internet or even you would like to display images from PHAsset from Photos framework. All you need is implement protocol INSPhotoViewable to your CustomPhoto model and thats it!

public protocol INSPhotoViewable: class {
var image: UIImage? { get }
var thumbnailImage: UIImage? { get }
func loadImageWithCompletionHandler(completion: (image: UIImage?, error: NSError?) -> ())
func loadThumbnailImageWithCompletionHandler(completion: (image: UIImage?, error: NSError?) -> ())
var attributedTitle: NSAttributedString? { get }
}

This is how sample implementation will look like using HanekeSwift for downloading and caching images.

class CustomPhotoModel: NSObject, INSPhotoViewable {
var image: UIImage?
var thumbnailImage: UIImage?
var imageURL: NSURL?
var thumbnailImageURL: NSURL?

var attributedTitle: NSAttributedString?
func loadImageWithCompletionHandler(completion: (image: UIImage?, error: NSError?) -> ()) { if let url = imageURL {
Shared.imageCache.fetch(URL: url).onSuccess({ image in
completion(image: image, error: nil)
}).onFailure({ error in
completion(image: nil, error: error)
})
} else {
completion(image: nil, error: NSError(domain: “PhotoDomain”, code: -1, userInfo: [ NSLocalizedDescriptionKey: “Couldn’t load image”]))
}
}

There is nothing more to say, we hope this post was helpful and that INSPhotoGallery will help you building great apps. Example and source code is available in our GitHub repositery here! — enjoy.

--

--

Michał Zaborowski
inspace labs

iOS Developer, creator of Open-Source MZFormSheetController. Founder at @inspace_io