ImageUI is an open source project for displaying images and videos (not yet implemented) in a similar way to Apple’s Photos app. If you'd like to contribute to ImageUI see Contributing. In this version there is the photo browser that allows to display thumbnail and full-size images.
- Loading remote, local and in-memory images
- Support both portrait and landscape mode
- Sharing, deleting and custom actions
- Size class adaptive layout (iOS, iPadOS)
- Dark mode
- Multiple gestures (tap, double tap, pan, swipe, pinch)
- LPLinkMetadata (iOS 13.0+)
- SwiftUI compatible
- iOS 11.0+
- Xcode 11+
- Swift 5.1+
Powerful Image Loading System
CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate ImageUI into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'ImageUI'
Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate ImageUI into your Xcode project using Carthage, specify it in your Cartfile
:
github "alberto093/ImageUI"
Swift Package Manager is a dependency manager built into Xcode.
If you are using Xcode 11 or higher, go to File / Swift Packages / Add Package Dependency... and enter package repository URL https://github.com/alberto093/ImageUI.git, then follow the instructions.
Once you have your Swift package set up, adding ImageUI as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/alberto093/ImageUI.git")
]
IFImage is the data structure that represents the image metadata. You can instantiate an IFImage in a three different ways:
let urlImage = IFImage(url: imageURL) // network URL
let fileImage = IFImage(path: filePath) // file URL (path)
let memoryImage = IFImage(image: myUIImage) // in-memory image
To get the best performances you should provide both the thumbnail and full-size images especially if you are using network URLs. Optionally you can provide a title that represents the navigation bar title (and the sharing metadata title available on iOS 13.0+) and a loading placeholder image.
let image = IFImage(
title: "First image",
original: .remote(url: imageURL),
thumbnail: .remote(url: thumbnailURL),
placeholder: loadingImage)
Ideally the thumbnail images' sizes should be smaller than 300x300 (the maximum size on iPad)
IFBrowserViewController represents the container of both thumbnails and full-size images.
It is possibile to use it directly in Storyboard or programmatically and It does not require a UINavigationController
but It is strongly recommended.
let viewController = IFBrowserViewController(images: images, initialImageIndex: 0)
viewController.configuration.actions = [.share, .delete]
// Navigation controller
navigationController.pushViewController(viewController, animated: true)
// Modal presentation
let navigationController = UINavigationController(rootViewController: browserViewController)
navigationController.modalPresentationStyle = .fullScreen
present(navigationController, animated: true)
Custom presentation controllers and custom animators
UIViewControllerInteractiveTransitioning
,UIViewControllerAnimatedTransitioning
are work in progress.
It is possible to set the initial displaying image index.
// images: [IFImage]
let viewController = IFBrowserViewController(images: images, initialImageIndex: .random(in: images.indices))
The
IFBrowserViewController
clamps the provided value to avoid unexpected crash.
The IFBrowserViewController
allows you to decide whether the full-size image should be displayed using the aspect fill zoom if the aspect ratio is similar to its container view.
let viewController = IFBrowserViewController(
images: images,
initialImageIndex: 0)
viewController.configuration.prefersAspectFillZoom = false
let viewController = IFBrowserViewController(
images: images,
initialImageIndex: 0)
viewController.configuration.prefersAspectFillZoom = true
It is possibile to create a custom action to allow user to interact with images.
browserViewController.configuration.actions = [.share, .custom(identifier: "cropAction", image: cropImage)]
Sharing and deleting actions are already managed by the
IFBrowserViewController
.
Then you can interact with them by implementing IFBrowserViewControllerDelegate
:
func browserViewController(_ browserViewController: IFBrowserViewController, didSelectActionWith identifier: String, forImageAt index: Int) {
switch identifier {
case "cropAction":
// User tap on crop action
default:
break
}
}
The browser implements the default cancel bar button item when it is presented modally. You can provide your own bar button item by setting navigation item related-property:
browserViewController.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .close, target: self, action: #selector(closeButtonDidTap))
It is recommended to subclass
IFBrowserViewController
instead of provide a button with an another target
It is possible to provide a title or a title view to avoid automatic updates when a new image is about to be displayed.
browserViewController.navigationItem.titleView = CustomLabel(title: "ImageUI", subtitle: "My album")
You can adopt IFBrowserViewControllerDelegate
and implement the following method in order to update the UI by your rules.
func browserViewController(_ browserViewController: IFBrowserViewController, willDisplayImageAt index: Int) {
// A new image is about to be displayed
}
ImageUI's roadmap is managed by Trello and is publicly available. If you'd like to contribute, please feel free to create a PR.
ImageUI is released under the MIT license. See LICENSE for details.