A photo gallery for iOS with a modern feature set. Similar features as the Facebook photo browser.

Related tags

Image EBPhotoPages
Overview

EBPhotoPages

”A photo gallery can become a pretty complex component of an app very quickly. The EBPhotoPages project demonstrates how a developer could use the State Pattern to control the behavior of an interface with numerous features. This pattern grants the ability to create new behaviors for a custom implementation of the EBPhotoPages photo gallery without having to modify or understand much of the original source code. The goal was to design a photo gallery class that would smoothly support whatever use cases would be required in the future.”

Alt text|Alt text Alt text Alt text|Alt text Alt text|Alt text Alt text

What is this?

EBPhotoPages is a photo gallery library for displaying pages of photos and their meta data in a scrollview. Users are able to zoom photos in and out, as well as create, edit or delete comments and tags, share or delete a photo, and report inappropriate photos. All photos and content are loaded asynchronously. User permissions for a photo are controlled through a delegate protocol. No graphic files are required for the gallery as icons are drawn in code.

The library was designed using a state pattern to control the behavior of the gallery, so that other developers can easily modify or add new states without having to understand too much of the original code.

Quick Feature list:

  • Photo Tagging: Create/Edit/Delete
  • Photo Commenting: Create/Edit/Delete
  • Photo Sharing:
  • Photo Reporting:
  • Speficy User Permissions per Photo for commenting, tagging, deletion, reporting, etc.
  • Page Based Scrolling
  • Photos give immediate bounce feedback when single tapped, for a juicy interface feel.
  • Toggle Tags On/Off
  • Pinch, Zoom, Pan Photos with gestures.
  • Scrollable captions, variable lengths with auto-dimming background
  • Show/Hide UI elements with a single tap gesture
  • Asynchronous loading of data (through NSOperationQueue)
  • Activity Indicator per Photo.
  • Content Mode AspectFit/Center auto detection (prevent photos smaller than the screen from blowing up)
  • Full landscape/portrait orientation support
  • Resolution independent support (iPad/iPhone)
  • Touch and hold comments to copy or delete
  • Flat UI Design
  • Comments icon shows the number of comments posted (if there are any)
  • Other stuff

How do I use it?

  1. Add the QuartzCore.framework, CoreGraphics.framework and AVFoundation.framework to your project.

  2. Add the EBPhotoPagesController folder from this repo to your app.

  3. Implement the EBPhotoPagesDataSource(required) and EBPhotoPagesDelegate(optional) protocols in an object(s) you plan to use as the datasource and delegate for your EBPhotoPagesController instance.

  4. Then, initialize and present the photoPagesController:

EBPhotoPagesController *photoPagesController = [[EBPhotoPagesController alloc] 
                                               initWithDataSource:aDataSource delegate:aDelegate];

[self presentViewController:photoPagesController animated:YES completion:nil];

How do I customize this?

The EBPhotoPagesFactory class is meant to be the one-stop shop for all UI objects. This class is responsible for instantiaing UI Elements and returning them to the EBPhotoPagesController. If you wish to customize the look of your photo gallery implementation, this is the first place you should check for whatever you want to customize. Some other UI elements are not yet created by this class, but the plan is to eventually move them into it.

By subclassing this class and overriding relevant methods, you can control how the UI objects will look before they get sent back to the EBPhotoPagesController to be used.

If you are going to create a custom EBPhotoPagesFactory subclass, you will have to init your EBPhotoPagesController with one of the init methods that lets you pass an EBPhotoPagesFactory instance, such as this one:

- (id)initWithDataSource:(id<EBPhotoPagesDataSource>)dataSource 
                delegate:(id<EBPhotoPagesDelegate>)aDelegate 
       photoPagesFactory:(EBPhotoPagesFactory *)factory 
            photoAtIndex:(NSInteger)index

How do State Objects work in EBPhotoPages?

At any given time, the photo gallery has a state object assigned as its current state, when a user event is received, the photo gallery’s state object takes responsibility for how the photo gallery should respond.

By convention, state objects are decoupled from each other. This means they are completely unaware of other state objects, and they also hold no data of their own. You can freely create and destroy them without fear (or guilt…).

When a state object decides it’s time to transition to a new state, it simply calls upon a method within the photo gallery that replaces the current state object with a new instance of the next state object.

To create a new custom State for your implementation of the photo gallery, you should do two things:

  1. Create a new state object that is a subclass of the EBPhotoPagesState object, and override the methods you’re interested in. (example: EBPhotoPagesCoolNewState)

  2. Create a category of the EBPhotoPages that contains the method(s) for your custom transitions. The purpose of a transition method is usually to set the “currentState” object of the EBPhotoPagesController to a new instance of your new custom state. (example: -(void)transitionToCoolNewState;)

  3. Decide how the user will reach this new custom state. If there is a special button in the interface that takes the user to this state when tapped, then make sure the EBPhotoPages calls your new transition method for that user event. If you are injecting this custom state somewhere in between the default state machine flow (the normal default behavior of the EBPhotoPagesController), then this may require a bit more overriding of existing classes so that your new state is reached instead of the original ones.

  4. Don’t forget to implement some way for a user to exit your custom state and go back to a default idle browsing state!

Tell me more about the features.

  • Tags: If you don’t already know, a tag is a point of interest at a certain spot within a photo (usually a person’s face). A tag’s coordinates in a photo are normalized between 0 and 1, so that the point is independent of the actual photo’s current resolution. For usability purposes, tags do not sit exactly on the pixel that was tagged, but rather they have padding that positions them a few pixels below it so the point of interest isn’t overly obscured by the tag.

  • Comments: As you can imagine, a comment is a user submitted text that accompanies a photo. The comment also includes meta data such as the user’s name, their avatar, and time of posting. The order of the comments appearance is determined by the order in which the datasource returns them.

  • Zero Graphic Files: Amazingly, the EBPhotoPages library requires no graphic files for its default toolbar icons because everything is drawn natively in code and converted to a UIImage. However, if you want to use actual graphic files for custom icons, you can always provide them directly by returning them through the appropriate methods as well.

  • Sharing: The EBPhotoPages provide a default activity sheet for sharing a photo. You can customize what kind of sheet and services are displayed by returning a custom one from your datasource object.

  • Reporting Photos: When a user comes across inappropriate content there needs to be a way to let them report it. The EBPhotoPages provides a report option that informs your datasource that a photo has to be marked as inappropriate.

What are some things to consider when implementing EBPhotoPages?

  • Caching: The EBPhotoPages do not implement their own caching system for photo content. That responsibility is passed on to whatever you decide to use as the datasource for the EBPhotoPages. You should probably pre-fetch content ahead of time and save it for faster loading if speed is a concern (which is usually the case…).

  • User Permission: When a user takes some action on a photo such as commenting or tagging or deleting (and others), the EBPhotoPages will ask its delegate if the user has permission to do that. This approach creates flexibility in controlling what a user can and can’t do on a per-photo basis. This means you should think about how to organize user permissions on your end.

  • Creating/Destroying content: Prepare your backend for the ability to post new content or delete existing content when the EBPhotoPages notifies your delegate that the user has initiated such an action. It would not be a good idea to let the EBPhotoPages itself be responsible for actual removing or posting the data to your servers directly.

How can I help?

Although this library has a lot of features and over 5,000 lines of code, there’s still some challenges to solve. Feel free to improve on the library and submit pull requests. In particular, these areas need some attention:

  • More Caption Content: The caption block might be a good place to show the number of likes a photo has, along with the author, date of posting, location and whether the photo is private or public. Bonus if these things are tappable.

  • Page Indicator: A page indicator that shows how many photos there are and which photo you are currently on (perhaps in the top left corner) would be useful.

  • TagPopovers: Bless the tag popovers, they do their best to stay within the photo boundaries so they are not cut off screen, but this behavior could still be improved. Right now, the implementation is a bit simplistic, the arrow points need to be drawn closer to where the actual tagged pixel is, not just shoved along. Consideration of a photo’s zoom scale should also be taken into account.

  • Deleting stuff: Once upon a time deleting photos worked flawlessly, but somewhere along the way there was an update and something broke and now it’s kind of buggy (though photos do delete from the datasource). The main problem is that the UIPageViewController doesn't discard the old view controller of the deleted photo until you scroll it out of existence.

  • Alternative toolbar layouts: The current toolbars work fine, but there’s always better or different ways of doing things. If a developer could simply set a toolbar to adopt a different layout style by just setting an enumerated property to a new value that would be sweet. The more variety the better.

  • iOS 7 features: This project was started a bit before iOS 7. Having the option to include some of the physics based features or parallax into the gallery would be awesome. Remember to add a property to toggle these on and off.

  • Networking: The code related to loading content is made to run asynchronously, but it has not been thoroughly tested on a consumer web scale application of any sort. Someone with more experience here may want to try offering some improvements from practical experience.

  • Likes: One of the more noticeable features missing from EBPhotoPages is the ability to “like” photos.

  • Localization: Every string used for the interface is ready for localization with NSLocalizedString. Currently, there are no localization files provided with the library so only English is represented. If you want your language for your culture represented, you should consider adding and sharing localization files to the project!

  • Comment Pagination: When a photo amasses an staggering number of comments, it would be impractical to make a web request for all of them at once. A system for allowing pagination of comments is needed, as currently the EBPhotoPages does not allow for new comments to be loaded in by user request. Another alternative is to implement an infinite scroll, by informing the datasource what cell a user has scrolled to in the comments so that it may download more comments as needed.

  • Presentation Transitions: Originally the EBPhotoPages was intendend to expand from a thumbnail into a full gallery, then shrink back to an image thumbnail when the user exited the gallery. This was never implemented, however, there are other variations of transitions that would be interesting to see as well.

Any issues or bugs?

  • The loading indicator has a tendency to not show up sometimes.
  • Deleting comments doesn’t animate too smoothly.
  • (!)Deleting a photo doesn't remove it immediately from the gallery, scrolling backward shows old data. (However, the photo is still deleted from the data model)
  • (!)Deleting a photo at the end of the gallery is causing a crash perhaps due to scrolling beyond index?
  • Creating tags while in landscape mode is a bit messed up.
  • Editing a tag doesn't work at the moment.
  • Toolbar icons disappear after deleting a tag, have to tap photo twice to return them.
  • When long pressing a comment to view Copy and Delete options, only the relevant comment should stay highlighted.
  • Long pressing a photo then selecting the Tag Photo option should start a new tag at the location of the longpress, instead of just entering the tagging mode.

Got a License?

EBPhotoPages uses the MIT License:

Copyright (c) 2014 Eddy Borja

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Who made this?

EBPhotoPages and its components were created by Eddy Borja.

iPhone PSD Template by Mikael Eidenberg.

These days I'm unable to continue working on this project due to other obligations, but I'm always open to pull requests.

Contributors can always be found here.

What else?

Be sure to check out these other libraries:

MLPSpotlight
UIColor+MLPFlatColors
MLPAccessoryBadge
MLPAutoCompleteTextField

Issues
  • How can I show HTTP pictures not local pics ?

    How can I show HTTP pictures not local pics ?

    I cant find how can I initiate pictures with NSURL

    opened by isayeter 8
  • can default select photo when i use in the more photos ?

    can default select photo when i use in the more photos ?

    Hi, Eddy sorry, my english isn't good. i use this EBPhotoPages to my app, have an one questions, when i bind 3 photos in the one TableViewCell, i click it, but always begin EBPhotoPages at photo 1, how to set default photo index when i click photo 2... T.T

    thank you. Eric

    opened by ilyi1116 4
  • Few commits

    Few commits

    Hey Eddy, love the project. I went ahead and updated the .gitignore file, removed the sizewithfont stuff, and added an animation when deleting a tag.

    I actually left a few animations in there for the tag deletion, right now it just makes scale to 0,0, but the other options are reduce its alpha, move it off screen, and I'm sure theres plenty more depending on what you want to do.

    I tried looking at the deletion issue, its very weird to me, I'm not sure why that happens but id like to look at it more in the future.

    enhancement 
    opened by thefotes 3
  • Toolbars alpha configurable in factory

    Toolbars alpha configurable in factory

    I've noticed that you can't really change the alpha for toolbars - there is one off method but every time you click on activity or share button the alpha gets restored back to 1.0 value ignoring whatever was the last alpha set. I've added methods to factory which can override the default alpha for toolbars.

    opened by 3ph 3
  • Can't write a comment on a 3.5 inch screen.

    Can't write a comment on a 3.5 inch screen.

    That's it thx for the amazing work!

    plus uipageviewcontroller is complex....T.T

    unverified 
    opened by zzz6519003 2
  • Hide ... if setDisabledDelete

    Hide ... if setDisabledDelete

    In this situation please remove the ... button as it does nothing.

    screen shot 2014-04-27 at 12 44 07 pm

    enhancement 
    opened by fulldecent 2
  • Update EBPhotoPagesController.m

    Update EBPhotoPagesController.m

    Missing parameter

    opened by jbdujardin 1
  • Comments lower toolbar button not hidden when comments disabled

    Comments lower toolbar button not hidden when comments disabled

    There's a bug on this line,

    https://github.com/EddyBorja/EBPhotoPages/blob/master/EBPhotoPagesController/EBPhotoPagesController.m#L277

    Should be lowerItems not upper.

    opened by JoeMatt 1
  • Update UIActionViewController popover for iOS8 on iPad.

    Update UIActionViewController popover for iOS8 on iPad.

    The "share" UIActionViewController was crashing on iOS8 on the iPad due to new requirements that a "popoverPresentationController" item be set for the UIActionViewController to display "from". This update uses the share button as that frame of reference.

    opened by adamgall 1
  • Swift Package Manager

    Swift Package Manager

    • Removed some warning on new versione of Xcode;
    • Added new Package Swift Manager;
    • Fix UI for the device with notch
    opened by m-ricca 0
  • anchor view

    anchor view

    how to show arrow dynamically but it shows only up words its urgent thanks in andvance

    opened by mitesh53 0
  • Enable customizing the user interface of the image viewer

    Enable customizing the user interface of the image viewer

    I created a global class called EBConfig that allows developers to change different features of the user interface easily e.g font, font color, date formatting etc.

    I also added a feature to load the comment avatars from aNSURL opposed to a UIImage incase there is networking involved. Feel free to change anything, I just had to change a few things to work for my project.

    opened by jesster2k10 0
  • Is this repo still being mantained?

    Is this repo still being mantained?

    Hey @EddyBorja, are you still maintaining this control? I would like to use it, but I see lot's of things you use here were deprecated and that's kind of a show stopper to me... Any idea if you'll be able to keep working in this? If not I think it might be a good idea to find someone to transfer the project to :)

    opened by mradzinski 6
  • Possible problem with Apple's Private APIs

    Possible problem with Apple's Private APIs

    My app just got rejected with this message:

    Your app uses or references the following non-public APIs:

    commentText

    Searching my project for this string showed only the classes in your library. This is obviously a false positive from Apple since I used this library for the last couple of months and updated my app with no problems what so ever. You might want to rename the "commentText" method in EBPhotoCommentProtocol and the selectors that reference this method

    opened by potecuta 0
  • Can I load videos from web services?

    Can I load videos from web services?

    I want to display videos from my webservices and that to in vertical scrolling, is that possible using this library?

    opened by Neeraj204 0
  • cannot hide commentsBarButtonItem

    cannot hide commentsBarButtonItem

    Haven't remove commentsBarButtonItem from mutableLowerItems while checking commentsAreViewable. Please refer to the last line at source code below from EBPhotoPagesController.m

    solution: change [mutableUpperItems removeObject:self.commentsBarButtonItem]; to [mutableLowerItems removeObject:self.commentsBarButtonItem];

    • (void)updateToolbarsWithPhotoAtIndex:(NSInteger)index { NSArray *upperItems = [self.photoPagesFactory upperToolbarItemsForPhotoPagesController:self inState:self.currentState];

      NSArray *lowerItems = [self.photoPagesFactory lowerToolbarItemsForPhotoPagesController:self inState:self.currentState];

      NSMutableArray *mutableUpperItems = [NSMutableArray arrayWithArray:upperItems]; NSMutableArray *mutableLowerItems = [NSMutableArray arrayWithArray:lowerItems];

      BOOL taggingAllowed = [self.photosDataSource respondsToSelector:@selector(photoPagesController:shouldAllowTaggingForPhotoAtIndex:)] ? [self.photosDataSource photoPagesController:self shouldAllowTaggingForPhotoAtIndex:index] : YES;

      BOOL activitiesAllowed = [self.photosDataSource respondsToSelector:@selector(photoPagesController:shouldAllowActivitiesForPhotoAtIndex:)] ? [self.photosDataSource photoPagesController:self shouldAllowActivitiesForPhotoAtIndex:index] : YES;

      BOOL commentsAreViewable = [self.photosDataSource respondsToSelector:@selector(photoPagesController:shouldShowCommentsForPhotoAtIndex:)] ? [self.photosDataSource photoPagesController:self shouldShowCommentsForPhotoAtIndex:index] : YES;

      if([self.photosDataSource photoPagesController:self shouldExpectPhotoAtIndex:index] == NO){ taggingAllowed = NO; activitiesAllowed = NO; commentsAreViewable = NO; }

      if(taggingAllowed == NO){ [mutableUpperItems removeObject:self.tagBarButtonItem]; [mutableLowerItems removeObject:self.tagBarButtonItem]; }

      if(activitiesAllowed == NO){ [mutableUpperItems removeObject:self.activityBarButtonItem]; [mutableLowerItems removeObject:self.activityBarButtonItem]; }

      if(commentsAreViewable == NO){ [mutableUpperItems removeObject:self.commentsBarButtonItem]; [mutableUpperItems removeObject:self.commentsBarButtonItem]; }

    opened by flysec 0
  • support for handle link url taps in caption text

    support for handle link url taps in caption text

    Wonderfull library, thank you for your effort. I found this method and "attributedCaptionForPhotoAtIndex" and try to used. It's very good for using with HTML attributes like . But when I try to use with Click this... it's not able handle open URL. I checked that part of code and see that using UILabel with setAttributedText.

    Is there any plan to adding this functionality for library in near future?

    opened by gurhub 1
  • Can load images from URL?

    Can load images from URL?

    Hi i'm use loading images from URL it's posible use in this library?

    opened by ingscjoshua 2
  • How to remove lower tool bar ?

    How to remove lower tool bar ?

    Hi, I used EBPhotoPage in my project.Now i'm set all images and get pinch and zoom.But my requirement is no need to show bottom tool bar.I just shown images with their details only.So can handle that functionality.

    Thanks, Sudalaiyandi

    opened by sudalainaz 1
Releases(0.9.1)
  • 0.9.1(Apr 10, 2014)

    SizeWithFont has been replaced, tag deletions animate, "Commenting is Disabled." placeholder text added when commenting isn't allowed, and some other minor stuff.

    Source code(tar.gz)
    Source code(zip)
Owner
Eddy Borja
The sky above the port was the color of television, tuned to a dead channel.
Eddy Borja
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 238 Nov 13, 2021
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

Thiago Peres 2.7k Nov 11, 2021
iOS photo gallery written in Swift

SwiftPhotoGallery Overview A full screen photo gallery for iOS and tvOS written in Swift. Photos can be panned and zoomed (iOS only) Pinch to zoom (iO

Justin Vallely 241 Nov 12, 2021
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

Alex Hill 562 Nov 25, 2021
A simple iOS photo and video browser with grid view, captions and selections.

MWPhotoBrowser A simple iOS photo and video browser with optional grid view, captions and selections. MWPhotoBrowser can display one or more images or

Michael Waterfall 8.8k Nov 11, 2021
Elegant photo browser in Swift. 图片与视频浏览器。

Elegant photo browser in Swift. 图片与视频浏览器。

JiongXing 1.1k Nov 26, 2021
A modern photo viewing experience for iOS.

NYTPhotoViewer NYTPhotoViewer is a slideshow and image viewer that includes double-tap to zoom, captions, support for multiple images, interactive fli

The New York Times 2.8k Nov 14, 2021
A modern, simple and zero-dependency photo picker with an elegant and customizable image editor

FMPhotoPicker is a modern, simple and zero-dependency photo picker with an elegant and customizable image editor Quick demo Batch select/deselect Smoo

Cong Nguyen 547 Nov 6, 2021
Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift

SKPhotoBrowser Simple PhotoBrowser/Viewer inspired by facebook, twitter photo browsers written by swift features Display one or more images by providi

keishi suzuki 2.3k Nov 24, 2021
FacebookImagePicker is Facebook album photo picker written in Swift.

Features • Installation • Usage • Translation • License GBHFacebookImagePicker is Facebook's album photo picker written in Swift, built to provide a s

Florian Gabach 223 Sep 1, 2021
A thread safe, performant, feature rich image fetcher

PINRemoteImage Fast, non-deadlocking parallel image downloader and cache for iOS PINRemoteImageManager is an image downloading, processing and caching

Pinterest 3.9k Nov 19, 2021
📷 multiple phassets picker for iOS lib. like a facebook

Written in Swift 5.0 TLPhotoPicker enables application to pick images and videos from multiple smart album in iOS, similar to the current facebook app

junhyi park 1.8k Nov 20, 2021
Slide image viewer library similar to Twitter and LINE.

Overview You can use it simply by passing the necessary information! Serrata is a UI library that allows you to intuitively view images. Features King

Takuma Horiuchi 324 Aug 27, 2021
A view that takes a set of images, make transition from one to another by using flipping effects.

CDFlipView A view that takes a set of images, make transition from one to another by using flipping effects. Demo Live Demo: https://appetize.io/app/w

Jianbin LIN 99 Aug 27, 2021
Style Art library process images using COREML with a set of pre trained machine learning models and convert them to Art style.

StyleArt Style Art is a library that process images using COREML with a set of pre trained machine learning models and convert them to Art style. Prev

iLeaf Solutions Pvt. Ltd. 214 Nov 1, 2021
An image cropper / photo cropper for iOS like in the Contacts app with support for landscape orientation.

RSKImageCropper An image cropper for iOS like in the Contacts app with support for landscape orientation. Installation RSKImageCropper requires iOS 9.

Ruslan Skorb 2.4k Nov 18, 2021
Custom iOS camera and photo picker with editing capabilities

Overview Paparazzo is a component for picking and editing photos. Key Features ?? Taking photos using camera ?? Picking photos from user's photo libra

avito.tech 734 Nov 16, 2021
ImagePickerSheetController replicates the custom photo action sheet in iMessage.

ImagePickerSheetController About ImagePickerSheetController is a component that replicates the custom photo action sheet in iMessage. It's very simila

Laurin Brandner 1.5k Nov 16, 2021
Turn a photo of your food into a face

Megabite Megabite is a mobile app that automatically turns a photo of your food into a face. Read more about it here. Installation This project uses C

Aaron Randall 358 Jun 3, 2021