Skip to content

Commit

Permalink
Merge branch 'master' of github.com:JanGorman/Agrume into swift/4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
JanGorman committed Sep 19, 2018
2 parents c39d37f + dc02447 commit 68dc9ef
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 75 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ disabled_rules:
- force_cast
- colon
- unused_optional_binding
- vertical_parameter_alignment

excluded:
- Frameworks/SwiftyGif
48 changes: 30 additions & 18 deletions Agrume.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

/* Begin PBXBuildFile section */
94318E541D32612D0096215A /* AgrumeServiceLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94318E531D32612D0096215A /* AgrumeServiceLocator.swift */; };
F2539BA120F22E7700062C80 /* AgrumeOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2539BA020F22E7700062C80 /* AgrumeOverlayView.swift */; };
F2609E23209F047200E0E93D /* AgrumeDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2609E22209F047200E0E93D /* AgrumeDataSource.swift */; };
F2609E26209F06F800E0E93D /* AgrumeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2609E25209F06F800E0E93D /* AgrumeImage.swift */; };
F2609E28209F2BC600E0E93D /* Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2609E27209F2BC600E0E93D /* Background.swift */; };
F2609E28209F2BC600E0E93D /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2609E27209F2BC600E0E93D /* Configuration.swift */; };
F2609E2A209F2E0200E0E93D /* UIKit+Agrume.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2609E29209F2E0200E0E93D /* UIKit+Agrume.swift */; };
F2A51FF41B10E00700924912 /* Agrume.h in Headers */ = {isa = PBXBuildFile; fileRef = F2A51FF31B10E00700924912 /* Agrume.h */; settings = {ATTRIBUTES = (Public, ); }; };
F2A51FFA1B10E00700924912 /* Agrume.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F2A51FEE1B10E00700924912 /* Agrume.framework */; };
Expand All @@ -21,6 +22,13 @@
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
F2539B9820F22D5100062C80 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 3B18BAF31E289899009C125A;
remoteInfo = SwiftyGif;
};
F2A51FFB1B10E00700924912 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F2A51FE51B10E00700924912 /* Project object */;
Expand Down Expand Up @@ -49,20 +57,14 @@
remoteGlobalIDString = 3B18BAF41E289899009C125A;
remoteInfo = SwiftyGif;
};
F2D7BA1C20A47D1700D5EE66 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 3B18BAF31E289899009C125A;
remoteInfo = SwiftyGif;
};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
94318E531D32612D0096215A /* AgrumeServiceLocator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AgrumeServiceLocator.swift; sourceTree = "<group>"; };
F2539BA020F22E7700062C80 /* AgrumeOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgrumeOverlayView.swift; sourceTree = "<group>"; };
F2609E22209F047200E0E93D /* AgrumeDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgrumeDataSource.swift; sourceTree = "<group>"; };
F2609E25209F06F800E0E93D /* AgrumeImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgrumeImage.swift; sourceTree = "<group>"; };
F2609E27209F2BC600E0E93D /* Background.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Background.swift; sourceTree = "<group>"; };
F2609E27209F2BC600E0E93D /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = "<group>"; };
F2609E29209F2E0200E0E93D /* UIKit+Agrume.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIKit+Agrume.swift"; sourceTree = "<group>"; };
F2A51FEE1B10E00700924912 /* Agrume.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Agrume.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F2A51FF21B10E00700924912 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -95,13 +97,21 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
F2539B9A20F22D6F00062C80 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
F2A51FE41B10E00700924912 = {
isa = PBXGroup;
children = (
F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */,
F2A51FF01B10E00700924912 /* Agrume */,
F2A51FFD1B10E00700924912 /* AgrumeTests */,
F2A51FEF1B10E00700924912 /* Products */,
F2539B9A20F22D6F00062C80 /* Frameworks */,
);
indentWidth = 2;
sourceTree = "<group>";
Expand All @@ -124,12 +134,13 @@
F2D9598B1B1A108800073772 /* AgrumeCell.swift */,
F2609E22209F047200E0E93D /* AgrumeDataSource.swift */,
F2609E25209F06F800E0E93D /* AgrumeImage.swift */,
F2539BA020F22E7700062C80 /* AgrumeOverlayView.swift */,
94318E531D32612D0096215A /* AgrumeServiceLocator.swift */,
F2609E27209F2BC600E0E93D /* Configuration.swift */,
F2EE29AD209F31B800F281A2 /* Foundation+Agrume.swift */,
F2DC79D51B170C4B00818A8C /* ImageDownloader.swift */,
F2A51FF11B10E00700924912 /* Supporting Files */,
F2609E27209F2BC600E0E93D /* Background.swift */,
F2609E29209F2E0200E0E93D /* UIKit+Agrume.swift */,
F2EE29AD209F31B800F281A2 /* Foundation+Agrume.swift */,
);
path = Agrume;
sourceTree = "<group>";
Expand Down Expand Up @@ -195,7 +206,7 @@
buildRules = (
);
dependencies = (
F2D7BA1D20A47D1700D5EE66 /* PBXTargetDependency */,
F2539B9920F22D5100062C80 /* PBXTargetDependency */,
);
name = Agrume;
productName = Agrume;
Expand Down Expand Up @@ -331,9 +342,10 @@
F2D9598C1B1A108800073772 /* AgrumeCell.swift in Sources */,
F2609E26209F06F800E0E93D /* AgrumeImage.swift in Sources */,
F2609E2A209F2E0200E0E93D /* UIKit+Agrume.swift in Sources */,
F2609E28209F2BC600E0E93D /* Background.swift in Sources */,
F2609E28209F2BC600E0E93D /* Configuration.swift in Sources */,
F2EE29AE209F31B800F281A2 /* Foundation+Agrume.swift in Sources */,
F2DC79D61B170C4B00818A8C /* ImageDownloader.swift in Sources */,
F2539BA120F22E7700062C80 /* AgrumeOverlayView.swift in Sources */,
F2609E23209F047200E0E93D /* AgrumeDataSource.swift in Sources */,
F2A5200B1B10E29B00924912 /* Agrume.swift in Sources */,
94318E541D32612D0096215A /* AgrumeServiceLocator.swift in Sources */,
Expand All @@ -350,16 +362,16 @@
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
F2539B9920F22D5100062C80 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = SwiftyGif;
targetProxy = F2539B9820F22D5100062C80 /* PBXContainerItemProxy */;
};
F2A51FFC1B10E00700924912 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F2A51FED1B10E00700924912 /* Agrume */;
targetProxy = F2A51FFB1B10E00700924912 /* PBXContainerItemProxy */;
};
F2D7BA1D20A47D1700D5EE66 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = SwiftyGif;
targetProxy = F2D7BA1C20A47D1700D5EE66 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
Expand Down
101 changes: 73 additions & 28 deletions Agrume/Agrume.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ public final class Agrume: UIViewController {
private var images: [AgrumeImage]!
private let startIndex: Int
private let background: Background
private let dismissal: Dismissal

private var overlayView: UIView?
private weak var dataSource: AgrumeDataSource?

public typealias DownloadCompletion = (_ image: UIImage?) -> Void
Expand Down Expand Up @@ -41,49 +43,62 @@ public final class Agrume: UIViewController {

/// Initialize with a single image
///
/// - Parameter image: The image to present
/// - Parameter background: The background configuration
public convenience init(image: UIImage, background: Background = .colored(.black)) {
self.init(images: [image], background: background)
/// - Parameters:
/// - image: The image to present
/// - background: The background configuration
/// - dismissal: The dismiss configuration
public convenience init(image: UIImage, background: Background = .colored(.black), dismissal: Dismissal = .withPhysics) {
self.init(images: [image], background: background, dismissal: dismissal)
}

/// Initialize with a single image url
///
/// - Parameter url: The image url to present
/// - Parameter background: The background configuration
public convenience init(url: URL, background: Background = .colored(.black)) {
self.init(urls: [url], background: background)
/// - Parameters:
/// - url: The image url to present
/// - background: The background configuration
/// - dismissal: The dismiss configuration
public convenience init(url: URL, background: Background = .colored(.black), dismissal: Dismissal = .withPhysics) {
self.init(urls: [url], background: background, dismissal: dismissal)
}

/// Initialize with a data source
///
/// - Parameter dataSource: The `AgrumeDataSource` to use
/// - Parameter startIndex: The optional start index when showing multiple images
/// - Parameter background: The background configuration
public convenience init(dataSource: AgrumeDataSource, startIndex: Int = 0, background: Background = .colored(.black)) {
self.init(images: nil, dataSource: dataSource, startIndex: startIndex, background: background)
/// - Parameters:
/// - dataSource: The `AgrumeDataSource` to use
/// - startIndex: The optional start index when showing multiple images
/// - background: The background configuration
/// - dismissal: The dismiss configuration
public convenience init(dataSource: AgrumeDataSource, startIndex: Int = 0, background: Background = .colored(.black),
dismissal: Dismissal = .withPhysics) {
self.init(images: nil, dataSource: dataSource, startIndex: startIndex, background: background, dismissal: dismissal)
}

/// Initialize with an array of images
///
/// - Parameter images: The images to present
/// - Parameter startIndex: The optional start index when showing multiple images
/// - Parameter background: The background configuration
public convenience init(images: [UIImage], startIndex: Int = 0, background: Background = .colored(.black)) {
self.init(images: images, urls: nil, startIndex: startIndex, background: background)
/// - Parameters:
/// - images: The images to present
/// - startIndex: The optional start index when showing multiple images
/// - background: The background configuration
/// - dismissal: The dismiss configuration
public convenience init(images: [UIImage], startIndex: Int = 0, background: Background = .colored(.black),
dismissal: Dismissal = .withPhysics) {
self.init(images: images, urls: nil, startIndex: startIndex, background: background, dismissal: dismissal)
}

/// Initialize with an array of image urls
///
/// - Parameter urls: The image urls to present
/// - Parameter startIndex: The optional start index when showing multiple images
/// - Parameter background: The background configuration
public convenience init(urls: [URL], startIndex: Int = 0, background: Background = .colored(.black)) {
self.init(images: nil, urls: urls, startIndex: startIndex, background: background)
/// - Parameters:
/// - urls: The image urls to present
/// - startIndex: The optional start index when showing multiple images
/// - background: The background configuration
/// - dismissal: The dismiss configuration
public convenience init(urls: [URL], startIndex: Int = 0, background: Background = .colored(.black),
dismissal: Dismissal = .withPhysics) {
self.init(images: nil, urls: urls, startIndex: startIndex, background: background, dismissal: dismissal)
}

private init(images: [UIImage]? = nil, urls: [URL]? = nil, dataSource: AgrumeDataSource? = nil, startIndex: Int,
background: Background) {
background: Background, dismissal: Dismissal) {
switch (images, urls) {
case (let images?, nil):
self.images = images.map { AgrumeImage(image: $0) }
Expand All @@ -95,6 +110,7 @@ public final class Agrume: UIViewController {

self.startIndex = startIndex
self.background = background
self.dismissal = dismissal
super.init(nibName: nil, bundle: nil)

self.dataSource = dataSource ?? self
Expand Down Expand Up @@ -135,7 +151,7 @@ public final class Agrume: UIViewController {
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: style))
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurView.frame = view.frame
_blurView = blurView
_blurView = blurView
return _blurView!
}
private var _collectionView: UICollectionView?
Expand Down Expand Up @@ -185,8 +201,10 @@ public final class Agrume: UIViewController {
}

/// Present Agrume
/// - Parameter viewController: The UIViewController to present from
/// - Parameter backgroundSnapshotVC: Optional UIViewController that will be used as basis for a blurred background
///
/// - Parameters:
/// - viewController: The UIViewController to present from
/// - backgroundSnapshotVC: Optional UIViewController that will be used as basis for a blurred background
public func show(from viewController: UIViewController, backgroundSnapshotVC: UIViewController? = nil) {
backgroundSnapshot = (backgroundSnapshotVC ?? viewControllerForSnapshot(fromViewController: viewController))?.view.snapshot()
view.isUserInteractionEnabled = false
Expand Down Expand Up @@ -231,12 +249,24 @@ public final class Agrume: UIViewController {
animations: {
self.collectionView.alpha = 1
self.collectionView.transform = .identity
self.addOverlayView()
}, completion: { _ in
self.view.isUserInteractionEnabled = true
})
}
}
}

private func addOverlayView() {
if case .withButton(let button) = dismissal {
let overlayView = AgrumeOverlayView(closeButton: button)
overlayView.delegate = self
overlayView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
overlayView.frame = view.bounds
view.addSubview(overlayView)
self.overlayView = overlayView
}
}

private func viewControllerForSnapshot(fromViewController viewController: UIViewController) -> UIViewController? {
var presentingVC = viewController.view.window?.rootViewController
Expand Down Expand Up @@ -306,6 +336,11 @@ extension Agrume: UICollectionViewDataSource {
let cell: AgrumeCell = collectionView.dequeue(indexPath: indexPath)

cell.tapBehavior = tapBehavior
if case .withPhysics = dismissal {
cell.hasPhysics = true
} else {
cell.hasPhysics = false
}

spinner.alpha = 1
dataSource?.image(forIndex: indexPath.item) { [weak self] image in
Expand Down Expand Up @@ -350,6 +385,7 @@ extension Agrume: AgrumeCellDelegate {
animations: {
self.collectionView.alpha = 0
self.blurContainerView.alpha = 0
self.overlayView?.alpha = 0
}, completion: dismissCompletion)
}

Expand All @@ -362,6 +398,7 @@ extension Agrume: AgrumeCellDelegate {
animations: {
self.collectionView.alpha = 0
self.blurContainerView.alpha = 0
self.overlayView?.alpha = 0
let scaling: CGFloat = .maxScalingForExpandingOffscreen
self.collectionView.transform = CGAffineTransform(scaleX: scaling, y: scaling)
}, completion: dismissCompletion)
Expand All @@ -371,3 +408,11 @@ extension Agrume: AgrumeCellDelegate {
return dataSource?.numberOfImages == 1
}
}

extension Agrume: AgrumeOverlayViewDelegate {

func agrumeOverlayViewWantsToClose(_ view: AgrumeOverlayView) {
dismiss()
}

}
Loading

0 comments on commit 68dc9ef

Please sign in to comment.