Image slide-show viewer with multiple predefined transition styles, with ability to create new transitions with ease.

Overview

ATGMediaBrowser

Carthage compatible CocoaPods GitHub issues GitHub license

ATGMediaBrowser is an image slide-show viewer that supports multiple predefined transition styles, and also allows the client to define new transition styles. It supports both horizontal and vertical gestures to control transitions, and adding new transitions is fun and easy. Checkout some of the transition styles below;

Vertical Zoom In Out

Horizontal Slide In

Horizontal Slide Out

Horizontal Move In Out

It supports commonly expected features like pinch-zoom, double-tap-to-zoom, interactive dismiss transition, dismiss zoomed-out to target frame etc. You can choose between linear and carousel styles for the media browser.

Installation

Carthage

ATGMediaBrowser can be installed using Carthage. To do so, simply add the following line to your Cartfile;

github "altayer-digital/ATGMediaBrowser" ~> 1.0.0

Cocoapods

To use ATGMediaBrowser with cocoapods, add the following line to the Podfile;

pod 'ATGMediaBrowser', '~> 1.0'

Usage

The media browser can be used as shown below;

let mediaBrowser = MediaBrowserViewController(dataSource: self)
present(mediaBrowser, animated: true, completion: nil)

self needs to conform to MediaBrowserViewControllerDataSource protocol and implement following methods;

func numberOfItems(in mediaBrowser: MediaBrowserViewController) -> Int {

    // return number of images to be shown
}

func mediaBrowser(_ mediaBrowser: MediaBrowserViewController, imageAt index: Int, completion: @escaping MediaBrowserViewControllerDataSource.CompletionBlock) {

    // Fetch the required image here. Pass it to the completion
    // block along with the index, zoom scale, and error if any.
    completion(index, image, ZoomScale.default, nil)
}

Why this approach?

You might be asking, why didn't we accept images as an array of images or as an array of URLs? Well, the reason is we wanted to stick to single responsibility principle.

Holding an array of images in memory could be trivial for a small number of images, but if it becomes large enough to cause large memory footprints, we will need to start using caching inside media browser, which is not what media browser is supposed to do.

Accepting URLs will require media browser to do network requests, download and cache the images, and then display them. That's gonna break the single responsibility.

So, media browser will stay clear of all the roles it is not supposed to do, and will stick to what it does well. On the bright side, you can decide how you will download and cache the images, which library to use for the same and in fact, have total control over the contents.

Transitions

There are 8 built-in transitions available with ATGMediaBrowser. On top of this anyone can easily create new transitions using the ContentTransformer closure. More on that can be found in the custom transitions section.

In-built transitions

There are 8 built-in transitions available with ATGMediaBrowser. They are;

  • horizontalMoveInOut
  • verticalMoveInOut
  • horizontalSlideOut
  • verticalSlideOut
  • horizontalSlideIn
  • verticalSlideIn
  • horizontalZoomInOut
  • verticalZoomInOut

For transition to work the way it is expected, each transition type has to have it's related property set on the media browser. For example, horizontalZoomInOut requires horizontal gesture direction and previousToNext draw order.

mediaBrowser.contentTransformer = DefaultContentTransformers.horizontalZoomInOut
mediaBrowser.gestureDirection = .horizontal
mediaBrowser.drawOrder = .previousToNext

TADA!, With just 3 lines of code, you have changed your media browser's transition style.

Custom transitions

Creating custom transition is super easy and fun with ATGMediaBrowser. The basic concept of ATGMediaBrowser transition is that there will be 3 views always in memory, and this will not change even if the total number of images to be shown is 1 or 10,000. The transition closure will be updating these three views' transform using the position passed into it. All the crazy stuff like transition progress, view reuse, zoom-in, zoom-out etc are already handled by ATGMediaBrowser. So, in order to create a custom transition, your responsibility will be to update the appearance of each content view corresponding to it's position.

There are 3 things to be done for creating a custom transition;

1. Choosing the gesture direction

It can be either horizontal or vertical. It does not necessarily needs to be a horizontal gesture for a horizontal transition. The direction simply defines the axis in which gesture will be detected, the transition can be in the opposite axis, if need be.

2. Choosing the draw order

The draw order can be either previousToNext or nextToPrevious.

previousToNext means left/top content view is drawn first, then middle view and then the right/bottom view. nextToPrevious means right/bottom content view is drawn first, then middle view and then the left/top view.

3. Implementing the ContentTransformer

The ContentTransformer is a closure which should update the appearance of content views based on the position. When a content view is at position0 the view should be visible to the user full screen. When the position is -1, the view should have the position and appearance of previous(top/left normally) item. When the position is 1, the view must be at next(bottom/right) item's position.

Below given is an example for the transition horizontalMoveInOut;

public static let horizontalMoveInOut: ContentTransformer = { contentView, position in

    let widthIncludingGap = contentView.bounds.size.width + MediaContentView.interItemSpacing
    contentView.transform = CGAffineTransform(translationX: widthIncludingGap * position, y: 0.0)
}

It is as simple as that.!

More Usage

Browser style

You can set the browser style to either linear or carousel. Carousel means that you can scroll the media items in circular fashion, and linear means, you can't. carousel is the default one.

mediaBrowser.browserStyle = .linear
Gap between media views

By default the gap will be 50.0 points.

mediaBrowser.gapBetweenMediaViews = 64.0

If you are implementing custom content transformer, you can access this value using MediaContentView.interItemSpacing

Show page control

Default is true. You can hide page control using the following code;

mediaBrowser.shouldShowPageControl = false
Show title

Default is false. You can show title using the following code;

mediaBrowser.shouldShowTitle = true
Hiding controls

By controls, we mean both page control and close button. You can set it to auto-hide using autoHideControls or show/hide them manually using hideControls.

mediaBrowser.autoHideControls = false
mediaBrowser.hideControls = false
Interactive dismissal

By default interactive dismissal is enabled. Interactive dismissal uses the gesture in direction orthogonal to the gestureDirection. You can disable the interaction as shown below;

mediaBrowser.enableInteractiveDismissal = false
Item Index

You can access the current index of the item in media browser using currentItemIndex variable.

Customizing close button

You can customize the close button using the data source call back func mediaBrowser(_ mediaBrowser: MediaBrowserViewController, updateCloseButton button: UIButton). You will be getting a UIButton instance in there, and you can customize the appearance, use auto-layout constraints to position it, even add target to get touch events on them.

If you do not add any constraints to the button, media browser will automatically add required constraints to keep it on top right of the screen.

Customizing title

Normally you can set title of mediaBrowser. You also can customize display title using delegate func mediaBrowser(_ mediaBrowser: ATGMediaBrowser.MediaBrowserViewController, didChangeFocusTo index: Int) to display appropriate title for the changed item index.

Dismissing the media browser into target frame

If you implement the func targetFrameForDismissal(_ mediaBrowser: MediaBrowserViewController) -> CGRect? method, the media browser will transition the currently shown image to the supplied target frame on dismissal.

Copyright and License

ATGMediaBrowser is available under the MIT license. See LICENSE.md for more information.

Contributors

List of contributors is available through GitHub.

You might also like...
Photo Browser / Viewer inspired by Facebook's and Tweetbot's with ARC support, swipe-to-dismiss, image progress and more
Photo Browser / Viewer inspired by Facebook's and Tweetbot's with ARC support, swipe-to-dismiss, image progress and more

IDMPhotoBrowser IDMPhotoBrowser is a new implementation based on MWPhotoBrowser. We've added both user experience and technical features inspired by F

Swift image slideshow with circular scrolling, timer and full screen viewer
Swift image slideshow with circular scrolling, timer and full screen viewer

🖼 ImageSlideshow Customizable Swift image slideshow with circular scrolling, timer and full screen viewer 📱 Example To run the example project, clon

add text(multiple line support) to imageView, edit, rotate or resize them as you want, then render the text on image
add text(multiple line support) to imageView, edit, rotate or resize them as you want, then render the text on image

StickerTextView is an subclass of UIImageView. You can add multiple text to it, edit, rotate, resize the text as you want with one finger, then render the text on Image.

FLImagePicker - A simple image picker supported multiple selection
FLImagePicker - A simple image picker supported multiple selection

FLImagePicker A simple image picker supported multiple selection. Features Multiple selection Gesture supported Dark mode Easy modification Installati

BeatboxiOS - A sample implementation for merging multiple video files and/or image files using AVFoundation

MergeVideos This is a sample implementation for merging multiple video files and

SwiftUI  project to show ActivityIndicator above Image while loading
SwiftUI project to show ActivityIndicator above Image while loading

ImageWithActivityIndicatorDemo SwiftUI project to show ActivityIndicator above Image while loading ImageWithActivityIndicatorDemo is a demo app that s

An iOS/tvOS photo gallery viewer, useful for viewing a large (or small!) number of photos.
An iOS/tvOS photo gallery viewer, useful for viewing a large (or small!) number of photos.

This project is unmaintained. Alex passed away in an accident in late 2019. His love of iOS development will always be remembered. AXPhotoViewer AXPho

Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift
Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift

SKPhotoBrowser [![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-) Simple PhotoBrowser

A simple mesh viewer for MacOS based on Swift and Metal and using Assimp for loading meshes

Metal Mesh Viewer A simple triangle mesh viewer for MacOS This application is a simple (triangle) mesh viewer that should be capable of rendering even

Comments
  • Some suggestions regarding this project

    Some suggestions regarding this project

    Hello!

    First of all, thank you for developing such a smooth pod. Unfortunately, I've come up with a several issues while trying to use this pod in my current project. I've some several suggestions to improve this project and if needed I can help develop it.

    • MediaBrowserViewController can't be used as a subclass because of the use of public class. A quick fix is to use open.
    • MediaBrowserViewController doesn't handle item count as 0. This is a problem working with async requests, since in the initial view load, the contents are 0, and then it's filled through either network request or file system req.
    • MediaBrowserViewController should have an empty state view, to indicate there's nothing to view. (This is related to the 2nd issue)
    • MediaBrowserViewConroller delegate can be and should be initialized after the constructor. Since, the developer may want to listen for delegate method changes after the view appeared, loaded etc.
    • There can be a support for RxSwift that can remove the uses of delegates and just use reactive programming to handle content change/reload.
    • Close button on top removes the ability for developers to use this pod as a tab inside tabbar controller. A simple check if the page is a root view controller can fix this.

    Hope this clears somethings from a user perspective of the pod.

    Btw, say hello to @mehmettamturk from me!

    opened by anonrig 1
Owner
null
A snappy image viewer with zoom and interactive dismissal transition.

A snappy image viewer with zoom and interactive dismissal transition. Features Double tap to zoom in/out Interactive dismissal transition Animate in f

Lucas 421 Dec 1, 2022
A snappy image viewer with zoom and interactive dismissal transition.

A snappy image viewer with zoom and interactive dismissal transition. Features Double tap to zoom in/out Interactive dismissal transition Animate in f

Lucas 421 Dec 1, 2022
Agrume - 🍋 An iOS image viewer written in Swift with support for multiple images.

Agrume An iOS image viewer written in Swift with support for multiple images. Requirements Swift 5.0 iOS 9.0+ Xcode 10.2+ Installation Use Swift Packa

Jan Gorman 601 Dec 26, 2022
DTPhotoViewerController - A fully customizable photo viewer ViewController to display single photo or collection of photos, inspired by Facebook photo viewer.

DTPhotoViewerController Example Demo video: https://youtu.be/aTLx4M4zsKk DTPhotoViewerController is very simple to use, if you want to display only on

Tung Vo 277 Dec 17, 2022
An extension that gives UIImageView the ability to focus on faces within an image.

FaceAware Sometimes the aspect ratios of images we need to work with don't quite fit within the confines of our UIImageViews. In most cases we can use

Beau Nouvelle 3k Jan 3, 2023
AYImageKit is a Swift Library for Async Image Downloading, Show Name's Initials and Can View image in Separate Screen.

AYImageKit AYImageKit is a Swift Library for Async Image Downloading. Features Async Image Downloading. Can Show Text Initials. Can have Custom Styles

Adnan Yousaf 11 Jan 10, 2022
A complete Mac App: drag an image file to the top section and the bottom section will show you the text of any QRCodes in the image.

QRDecode A complete Mac App: drag an image file to the top section and the bottom section will show you the text of any QRCodes in the image. QRDecode

David Phillip Oster 2 Oct 28, 2022
An image viewer à la Twitter

For the latest changes see the CHANGELOG Install CocoaPods pod 'ImageViewer' Carthage github "Krisiacik/ImageViewer" Sample Usage For a detailed examp

Kristian Angyal 2.4k Dec 29, 2022
Lightbox is a convenient and easy to use image viewer for your iOS app

Lightbox is a convenient and easy to use image viewer for your iOS app, packed with all the features you expect: Paginated image slideshow. V

HyperRedink 1.5k Dec 22, 2022
Image viewer (or Lightbox) with support for local and remote videos and images

Table of Contents Features Focus Browse Rotation Zoom tvOS Setup Installation License Author Features Focus Select an image to enter into lightbox mod

Nes 534 Jan 3, 2023