Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Example/Optik.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
0832454B1DA5BE40006F492E /* CustomToolbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0832454A1DA5BE40006F492E /* CustomToolbarController.swift */; };
486216831CE76A3A00686557 /* cats.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 4862167F1CE76A3A00686557 /* cats.jpg */; };
486216841CE76A3A00686557 /* life.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 486216801CE76A3A00686557 /* life.jpg */; };
486216861CE76A3A00686557 /* whiteboard.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 486216821CE76A3A00686557 /* whiteboard.jpg */; };
Expand All @@ -33,6 +34,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
0832454A1DA5BE40006F492E /* CustomToolbarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomToolbarController.swift; sourceTree = "<group>"; };
380B0038E4A48ADE86928EF5 /* Pods-Optik_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Optik_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Optik_Tests/Pods-Optik_Tests.debug.xcconfig"; sourceTree = "<group>"; };
4862167F1CE76A3A00686557 /* cats.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = cats.jpg; sourceTree = "<group>"; };
486216801CE76A3A00686557 /* life.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = life.jpg; sourceTree = "<group>"; };
Expand Down Expand Up @@ -116,6 +118,7 @@
children = (
607FACD51AFB9204008FA782 /* AppDelegate.swift */,
607FACD71AFB9204008FA782 /* ViewController.swift */,
0832454A1DA5BE40006F492E /* CustomToolbarController.swift */,
486216891CE76C4100686557 /* AlamofireImageDownloader.swift */,
607FACD91AFB9204008FA782 /* Main.storyboard */,
607FACDC1AFB9204008FA782 /* Images.xcassets */,
Expand Down Expand Up @@ -388,6 +391,7 @@
files = (
4862168A1CE76C4100686557 /* AlamofireImageDownloader.swift in Sources */,
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
0832454B1DA5BE40006F492E /* CustomToolbarController.swift in Sources */,
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
32 changes: 32 additions & 0 deletions Example/Optik/CustomToolbarController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// CustomToolbarController.swift
// Optik
//
// Created by Daniel Vancura on 10/5/16.
//
//

import Optik
import UIKit

internal final class CustomToolbarController: ToolbarController {

let navigationBarHidesOnTap = true

let toolbarHidesOnTap = true

let navigationItem: UINavigationItem = UINavigationItem(title: "Photos")

func setupNavigationBar(navigationBar: UINavigationBar, forUseIn albumViewController: UIViewController) {
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: #selector(share))
}

func setupToolbar(toolbar: UIToolbar, forUseIn albumViewController: UIViewController) {
toolbar.items = [UIBarButtonItem(title: "Nop", style: .Done, target: nil, action: nil)]
}

@objc private func share() {

}

}
3 changes: 2 additions & 1 deletion Example/Optik/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ internal final class ViewController: UIViewController {
@IBAction private func presentLocalImageViewer(sender: UIButton) {
let viewController = Optik.imageViewer(withImages: localImages,
initialImageDisplayIndex: currentLocalImageIndex,
delegate: self)
delegate: self,
toolbarController: CustomToolbarController())

presentViewController(viewController, animated: true, completion: nil)
}
Expand Down
204 changes: 151 additions & 53 deletions Optik/Classes/AlbumViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ internal final class AlbumViewController: UIViewController {
static let DismissButtonDimension: CGFloat = 60

static let TransitionAnimationDuration: NSTimeInterval = 0.3

static let toolbarHeight: CGFloat = 44.0
static let navbarHeight: CGFloat = 44.0
}

// MARK: - Properties

var toolbarController: ToolbarController?

weak var imageViewerDelegate: ImageViewerDelegate? {
didSet {
Expand Down Expand Up @@ -48,7 +53,7 @@ internal final class AlbumViewController: UIViewController {
}

// MARK: Private properties

private var pageViewController: UIPageViewController
private var currentImageViewController: ImageViewController? {
guard let viewControllers = pageViewController.viewControllers where viewControllers.count == 1 else {
Expand All @@ -57,6 +62,43 @@ internal final class AlbumViewController: UIViewController {

return viewControllers[0] as? ImageViewController
}

private var navigationBar: UINavigationBar?

private var toolbar: UIToolbar?

private var navigationBarHidden: Bool = false {
didSet {
UIView.animateWithDuration(Constants.TransitionAnimationDuration, animations: {
if self.navigationBarHidden {
self.navigationBar?.alpha = 0.0
self.navigationBar?.transform = CGAffineTransformMakeTranslation(0, -Constants.navbarHeight)
} else {
self.navigationBar?.alpha = 1.0
self.navigationBar?.transform = CGAffineTransformIdentity
}
})
}
}

private var toolbarHidden: Bool = false {
didSet {
UIView.animateWithDuration(Constants.TransitionAnimationDuration, animations: {
if self.toolbarHidden {
self.toolbar?.alpha = 0.0
self.toolbar?.transform = CGAffineTransformMakeTranslation(0, Constants.toolbarHeight)
} else {
self.toolbar?.alpha = 1.0
self.toolbar?.transform = CGAffineTransformIdentity
}

let scale = (self.pageViewController.view.bounds.height
- (self.navigationBarHidden ? CGFloat(0) : Constants.navbarHeight)
- (self.toolbarHidden ? CGFloat(0) : Constants.toolbarHeight)) / self.view.bounds.height
self.pageViewController.view.transform = CGAffineTransformMakeScale(scale, scale)
})
}
}

private var imageData: ImageData
private var initialImageDisplayIndex: Int
Expand All @@ -75,14 +117,17 @@ internal final class AlbumViewController: UIViewController {
initialImageDisplayIndex: Int,
activityIndicatorColor: UIColor?,
dismissButtonImage: UIImage?,
dismissButtonPosition: DismissButtonPosition) {
dismissButtonPosition: DismissButtonPosition,
toolbarController: ToolbarController? = nil) {

self.imageData = imageData
self.initialImageDisplayIndex = initialImageDisplayIndex
self.activityIndicatorColor = activityIndicatorColor
self.dismissButtonImage = dismissButtonImage
self.dismissButtonPosition = dismissButtonPosition


self.toolbarController = toolbarController

pageViewController = UIPageViewController(transitionStyle: .Scroll,
navigationOrientation: .Horizontal,
options: [UIPageViewControllerOptionInterPageSpacingKey : Constants.SpacingBetweenImages])
Expand All @@ -106,6 +151,9 @@ internal final class AlbumViewController: UIViewController {

override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)

navigationBarHidden = false
toolbarHidden = false

// HACK: UIKit doesn't animate status bar transition on iOS 9. So, manually animate it.
if !viewDidAppear {
Expand Down Expand Up @@ -145,14 +193,15 @@ internal final class AlbumViewController: UIViewController {
addChildViewController(pageViewController)
view.addSubview(pageViewController.view)
didMoveToParentViewController(pageViewController)
setupDismissButton()

setupToolbars()
setupPanGestureRecognizer()
}

private func setupPageViewController() {
pageViewController.dataSource = self
pageViewController.delegate = self
pageViewController.view.clipsToBounds = false

// Set up initial image view controller.
if let imageViewController = imageViewController(forIndex: initialImageDisplayIndex) {
Expand All @@ -162,54 +211,74 @@ internal final class AlbumViewController: UIViewController {
completion: nil)
}
}

private func setupDismissButton() {
let dismissButton = UIButton(type: .Custom)
dismissButton.translatesAutoresizingMaskIntoConstraints = false
dismissButton.setImage(dismissButtonImage, forState: .Normal)
dismissButton.addTarget(self, action: #selector(AlbumViewController.didTapDismissButton(_:)), forControlEvents: .TouchUpInside)

let xAnchorAttribute = dismissButtonPosition.xAnchorAttribute()
let yAnchorAttribute = dismissButtonPosition.yAnchorAttribute()

view.addSubview(dismissButton)

view.addConstraint(
NSLayoutConstraint(item: dismissButton,
attribute: xAnchorAttribute,
relatedBy: .Equal,
toItem: view,
attribute: xAnchorAttribute,
multiplier: 1,
constant: 0)
)
view.addConstraint(
NSLayoutConstraint(item: dismissButton,
attribute: yAnchorAttribute,
relatedBy: .Equal,
toItem: view,
attribute: yAnchorAttribute,
multiplier: 1,
constant: 0)
)
view.addConstraint(
NSLayoutConstraint(item: dismissButton,
attribute: .Width,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1,
constant: Constants.DismissButtonDimension)
)
view.addConstraint(
NSLayoutConstraint(item: dismissButton,
attribute: .Height,
relatedBy: .Equal,
toItem: nil,
attribute: .NotAnAttribute,
multiplier: 1,
constant: Constants.DismissButtonDimension)
)

private func setupToolbars() {
let navigationBar = UINavigationBar(frame: CGRect(
x: 0,
y: 0,
width: view.bounds.width,
height: Constants.navbarHeight
))
let toolbar = UIToolbar(frame: CGRect(
x: 0,
y: 0,
width: view.bounds.width,
height: Constants.toolbarHeight
))

let toolbarController = (self.toolbarController ?? DefaultToolbarController())

let dismissButton = UIBarButtonItem(image: dismissButtonImage, style: .Done, target: self, action: #selector(AlbumViewController.didTapDismissButton(_:)))
switch dismissButtonPosition {
case .TopLeading:
toolbarController.navigationItem.leftBarButtonItem = dismissButton
case .TopTrailing:
toolbarController.navigationItem.rightBarButtonItem = dismissButton
}

navigationBar.setItems([toolbarController.navigationItem], animated: false)
toolbarController.setupNavigationBar(navigationBar, forUseIn: self)
toolbarController.setupToolbar(toolbar, forUseIn: self)

let hideGestureRecognizer = UITapGestureRecognizer()

if toolbarController.navigationBarHidesOnTap {
hideGestureRecognizer.addTarget(self, action: #selector(toggleNavigationBar))
}

if toolbarController.toolbarHidesOnTap {
hideGestureRecognizer.addTarget(self, action: #selector(toggleToolbar))
}

view.addGestureRecognizer(hideGestureRecognizer)

view.addSubview(navigationBar)
view.addSubview(toolbar)

navigationBar.translatesAutoresizingMaskIntoConstraints = false
toolbar.translatesAutoresizingMaskIntoConstraints = false

setAttributeEqual(.Leading, for: view, from: view, to: navigationBar, with: 0)
setAttributeEqual(.Trailing, for: view, from: view, to: navigationBar, with: 0)
setAttributeEqual(.Top, for: view, from: topLayoutGuide, to: navigationBar, with: 0)

setAttributeEqual(.Leading, for: view, from: view, to: toolbar, with: 0)
setAttributeEqual(.Trailing, for: view, from: view, to: toolbar, with: 0)
setAttributeEqual(.Bottom, for: view, from: bottomLayoutGuide, to: toolbar, with: 0)

self.navigationBar = navigationBar
self.toolbar = toolbar
}

private func setAttributeEqual(attribute: NSLayoutAttribute, for view: UIView, from source: AnyObject, to destination: AnyObject, with distance: CGFloat) {
view.addConstraint(NSLayoutConstraint(
item: source,
attribute: attribute,
relatedBy: NSLayoutRelation.Equal,
toItem: destination,
attribute: attribute,
multiplier: 1.0,
constant: distance))
}

private func setupPanGestureRecognizer() {
Expand Down Expand Up @@ -257,6 +326,14 @@ internal final class AlbumViewController: UIViewController {
@objc private func didPan(sender: UIPanGestureRecognizer) {
transitionController.didPan(withGestureRecognizer: sender, sourceView: view)
}

@objc private func toggleNavigationBar() {
navigationBarHidden = !navigationBarHidden
}

@objc private func toggleToolbar() {
toolbarHidden = !toolbarHidden
}

}

Expand Down Expand Up @@ -308,5 +385,26 @@ extension AlbumViewController: UIPageViewControllerDelegate {
imageViewerDelegate?.imageViewerDidDisplayImage(atIndex: currentImageIndex)
}
}

func pageViewController(pageViewController: UIPageViewController, spineLocationForInterfaceOrientation orientation: UIInterfaceOrientation) -> UIPageViewControllerSpineLocation {
return .Max
}

func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return numberOfImages()
}

func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return currentImageViewController?.index ?? 0
}

private func numberOfImages() -> Int {
switch imageData {
case .Local(images: let images):
return images.count
case .Remote(urls: let urls, imageDownloader: _):
return urls.count
}
}

}
31 changes: 31 additions & 0 deletions Optik/Classes/DefaultToolbarController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// DefaultToolbarController.swift
// Pods
//
// Created by Daniel Vancura on 10/5/16.
//
//

import UIKit

internal final class DefaultToolbarController: ToolbarController {

// MARK: - Parameters

let navigationItem: UINavigationItem = UINavigationItem(title: "")

let navigationBarHidesOnTap: Bool = true

let toolbarHidesOnTap: Bool = true

// MARK: - Functions

func setupNavigationBar(navigationBar: UINavigationBar, forUseIn albumViewController: UIViewController) {
navigationBar.barStyle = .BlackTranslucent
}

func setupToolbar(toolbar: UIToolbar, forUseIn albumViewController: UIViewController) {
toolbar.barStyle = .BlackTranslucent
}

}
Loading