Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for animated gif images #86

Merged
merged 3 commits into from
May 10, 2018
Merged
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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "Frameworks/SwiftyGif"]
path = Frameworks/SwiftyGif
url = https://github.com/kirualex/SwiftyGif
6 changes: 4 additions & 2 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ trailing_whitespace:
cyclomatic_complexity:
warning: 15


opt_in_rules:
- attributes
- closure_end_indentation
Expand All @@ -48,4 +47,7 @@ opt_in_rules:
disabled_rules:
- force_cast
- colon
- unused_optional_binding
- unused_optional_binding

excluded:
- Frameworks/SwiftyGif
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ osx_image: xcode9.3
before_script:
- brew update && brew upgrade swiftlint
script:
- git submodule init
- bundle exec danger

6 changes: 4 additions & 2 deletions Agrume.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "Agrume"
s.version = "5.0.1"
s.version = "5.0.2"
s.summary = "An iOS image viewer written in Swift."
s.swift_version = "4.1"

Expand All @@ -20,6 +20,8 @@ Pod::Spec.new do |s|

s.source = { :git => "https://github.com/JanGorman/Agrume.git", :tag => s.version}

s.source_files = "Classes", "Agrume/*.swift"
s.source_files = "Classes", "Agrume/*.swift"

s.dependency "SwiftyGif"

end
76 changes: 76 additions & 0 deletions Agrume.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,34 @@
remoteGlobalIDString = F2A51FED1B10E00700924912;
remoteInfo = Agrume;
};
F2D7BA1620A47C6600D5EE66 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = FA29E9321CA9340E00E579D5;
remoteInfo = SwiftyGifExample;
};
F2D7BA1820A47C6600D5EE66 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = FA29E9461CA9340F00E579D5;
remoteInfo = SwiftyGifTests;
};
F2D7BA1A20A47C6600D5EE66 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3B18BAF41E289899009C125A;
remoteInfo = SwiftyGif;
};
F2D7BA1C20A47D1700D5EE66 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 3B18BAF31E289899009C125A;
remoteInfo = SwiftyGif;
};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
Expand All @@ -42,6 +70,7 @@
F2A51FF91B10E00700924912 /* AgrumeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AgrumeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
F2A51FFF1B10E00700924912 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F2A5200A1B10E29B00924912 /* Agrume.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Agrume.swift; sourceTree = "<group>"; };
F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SwiftyGif.xcodeproj; path = Frameworks/SwiftyGif/SwiftyGif.xcodeproj; sourceTree = "<group>"; };
F2D9598B1B1A108800073772 /* AgrumeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AgrumeCell.swift; sourceTree = "<group>"; };
F2DC79D51B170C4B00818A8C /* ImageDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageDownloader.swift; sourceTree = "<group>"; };
F2EE29AD209F31B800F281A2 /* Foundation+Agrume.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Foundation+Agrume.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -69,6 +98,7 @@
F2A51FE41B10E00700924912 = {
isa = PBXGroup;
children = (
F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */,
F2A51FF01B10E00700924912 /* Agrume */,
F2A51FFD1B10E00700924912 /* AgrumeTests */,
F2A51FEF1B10E00700924912 /* Products */,
Expand Down Expand Up @@ -128,6 +158,16 @@
name = "Supporting Files";
sourceTree = "<group>";
};
F2D7BA1120A47C6600D5EE66 /* Products */ = {
isa = PBXGroup;
children = (
F2D7BA1720A47C6600D5EE66 /* SwiftyGifExample.app */,
F2D7BA1920A47C6600D5EE66 /* SwiftyGifTests.xctest */,
F2D7BA1B20A47C6600D5EE66 /* SwiftyGif.framework */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand Down Expand Up @@ -155,6 +195,7 @@
buildRules = (
);
dependencies = (
F2D7BA1D20A47D1700D5EE66 /* PBXTargetDependency */,
);
name = Agrume;
productName = Agrume;
Expand Down Expand Up @@ -210,6 +251,12 @@
mainGroup = F2A51FE41B10E00700924912;
productRefGroup = F2A51FEF1B10E00700924912 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = F2D7BA1120A47C6600D5EE66 /* Products */;
ProjectRef = F2D7BA1020A47C6600D5EE66 /* SwiftyGif.xcodeproj */;
},
);
projectRoot = "";
targets = (
F2A51FED1B10E00700924912 /* Agrume */,
Expand All @@ -218,6 +265,30 @@
};
/* End PBXProject section */

/* Begin PBXReferenceProxy section */
F2D7BA1720A47C6600D5EE66 /* SwiftyGifExample.app */ = {
isa = PBXReferenceProxy;
fileType = wrapper.application;
path = SwiftyGifExample.app;
remoteRef = F2D7BA1620A47C6600D5EE66 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
F2D7BA1920A47C6600D5EE66 /* SwiftyGifTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = SwiftyGifTests.xctest;
remoteRef = F2D7BA1820A47C6600D5EE66 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
F2D7BA1B20A47C6600D5EE66 /* SwiftyGif.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = SwiftyGif.framework;
remoteRef = F2D7BA1A20A47C6600D5EE66 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */

/* Begin PBXResourcesBuildPhase section */
F2A51FEC1B10E00700924912 /* Resources */ = {
isa = PBXResourcesBuildPhase;
Expand Down Expand Up @@ -284,6 +355,11 @@
target = F2A51FED1B10E00700924912 /* Agrume */;
targetProxy = F2A51FFB1B10E00700924912 /* PBXContainerItemProxy */;
};
F2D7BA1D20A47D1700D5EE66 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = SwiftyGif;
targetProxy = F2D7BA1C20A47D1700D5EE66 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
Expand Down
15 changes: 6 additions & 9 deletions Agrume/Agrume.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ public final class Agrume: UIViewController {
/// Hide status bar when presenting. Defaults to `false`
public var hideStatusBar = false

/// Tap behaviour, i.e. what happens when you tap outside of the image area
public enum TapBehavior {
case dismissIfZoomedOut
case dismissAlways
case zoomOut
}
/// Default tap behaviour is to dismiss the view if zoomed out
public var tapBehavior: TapBehavior = .dismissIfZoomedOut

/// Initialize with a single image
Expand Down Expand Up @@ -177,6 +179,10 @@ public final class Agrume: UIViewController {
}

private var downloadTask: URLSessionDataTask?

public override var preferredStatusBarStyle: UIStatusBarStyle {
return statusBarStyle ?? super.preferredStatusBarStyle
}

/// Present Agrume
/// - Parameter viewController: The UIViewController to present from
Expand Down Expand Up @@ -365,12 +371,3 @@ extension Agrume: AgrumeCellDelegate {
return dataSource?.numberOfImages == 1
}
}

extension Agrume {

// MARK: Status Bar

public override var preferredStatusBarStyle: UIStatusBarStyle {
return statusBarStyle ?? super.preferredStatusBarStyle
}
}
7 changes: 6 additions & 1 deletion Agrume/AgrumeCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//

import UIKit
import SwiftyGif

protocol AgrumeCellDelegate: AnyObject {

Expand Down Expand Up @@ -39,7 +40,11 @@ final class AgrumeCell: UICollectionViewCell {

var image: UIImage? {
didSet {
imageView.image = image
if image?.imageData != nil, let image = image {
imageView.setGifImage(image)
} else {
imageView.image = image
}
updateScrollViewAndImageViewForCurrentMetrics()
}
}
Expand Down
29 changes: 23 additions & 6 deletions Agrume/ImageDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
//

import UIKit
import ImageIO
import MobileCoreServices
import SwiftyGif

final class ImageDownloader {

static func downloadImage(_ url: URL, completion: @escaping (_ image: UIImage?) -> Void) -> URLSessionDataTask? {
var configuration = URLSessionConfiguration.default
if #available(iOS 11.0, *) {
configuration.waitsForConnectivity = true
}
let session = URLSession(configuration: configuration)
let session = URLSession(configuration: newConfiguration())
let task = session.dataTask(with: url) { data, _, error in
var image: UIImage?
defer {
Expand All @@ -20,10 +19,28 @@ final class ImageDownloader {
}
}
guard let data = data, error == nil else { return }
image = UIImage(data: data)
if isAnimatedImage(data) {
image = UIImage(gifData: data)
} else {
image = UIImage(data: data)
}
}
task.resume()
return task
}

private static func newConfiguration() -> URLSessionConfiguration {
var configuration = URLSessionConfiguration.default
if #available(iOS 11.0, *) {
configuration.waitsForConnectivity = true
}
return configuration
}

private static func isAnimatedImage(_ data: Data) -> Bool {
guard let imageSource = CGImageSourceCreateWithData(data as CFData, nil),
let imageType = CGImageSourceGetType(imageSource) else { return false }
return UTTypeConformsTo(imageType, kUTTypeGIF)
}

}
1 change: 1 addition & 0 deletions Cartfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github "kirualex/SwiftyGif"
8 changes: 8 additions & 0 deletions Example/Agrume Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
F2A520201B130C7E00924912 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F2A5201E1B130C7E00924912 /* Main.storyboard */; };
F2A520221B130C7E00924912 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F2A520211B130C7E00924912 /* Images.xcassets */; };
F2A520251B130C7E00924912 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = F2A520231B130C7E00924912 /* LaunchScreen.xib */; };
F2D7BA1F20A47FB500D5EE66 /* AnimatedGifViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D7BA1E20A47FB500D5EE66 /* AnimatedGifViewController.swift */; };
F2D7BA2220A4812C00D5EE66 /* animated.gif in Resources */ = {isa = PBXBuildFile; fileRef = F2D7BA2120A4812C00D5EE66 /* animated.gif */; };
F2D9598E1B1A133800073772 /* SingleImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D9598D1B1A133800073772 /* SingleImageViewController.swift */; };
F2D959911B1A140200073772 /* SingleURLViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D959901B1A140200073772 /* SingleURLViewController.swift */; };
F2D959931B1A153F00073772 /* MultipleImagesCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D959921B1A153F00073772 /* MultipleImagesCollectionViewController.swift */; };
Expand Down Expand Up @@ -66,6 +68,8 @@
F2A5202A1B130C7E00924912 /* Agrume ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Agrume ExampleTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
F2A5202F1B130C7E00924912 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
F2A5203A1B130CC000924912 /* Agrume.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Agrume.xcodeproj; path = ../Agrume.xcodeproj; sourceTree = "<group>"; };
F2D7BA1E20A47FB500D5EE66 /* AnimatedGifViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimatedGifViewController.swift; sourceTree = "<group>"; };
F2D7BA2120A4812C00D5EE66 /* animated.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = animated.gif; sourceTree = "<group>"; };
F2D9598D1B1A133800073772 /* SingleImageViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleImageViewController.swift; sourceTree = "<group>"; };
F2D959901B1A140200073772 /* SingleURLViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleURLViewController.swift; sourceTree = "<group>"; };
F2D959921B1A153F00073772 /* MultipleImagesCollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipleImagesCollectionViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -116,6 +120,8 @@
F2A520171B130C7E00924912 /* Agrume Example */ = {
isa = PBXGroup;
children = (
F2D7BA2120A4812C00D5EE66 /* animated.gif */,
F2D7BA1E20A47FB500D5EE66 /* AnimatedGifViewController.swift */,
F2A5201A1B130C7E00924912 /* AppDelegate.swift */,
F2D959941B1A15ED00073772 /* DemoCell.swift */,
F2A520211B130C7E00924912 /* Images.xcassets */,
Expand Down Expand Up @@ -276,6 +282,7 @@
files = (
F2A520201B130C7E00924912 /* Main.storyboard in Resources */,
F2A520251B130C7E00924912 /* LaunchScreen.xib in Resources */,
F2D7BA2220A4812C00D5EE66 /* animated.gif in Resources */,
F2A520221B130C7E00924912 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -296,6 +303,7 @@
files = (
E77809E31D17821400CC60F1 /* SingleImageModalViewController.swift in Sources */,
F2D959911B1A140200073772 /* SingleURLViewController.swift in Sources */,
F2D7BA1F20A47FB500D5EE66 /* AnimatedGifViewController.swift in Sources */,
94D6B2121E1411B100927735 /* SingeImageBackgroundColorViewController.swift in Sources */,
F2A5201D1B130C7E00924912 /* ViewController.swift in Sources */,
F2D959951B1A15ED00073772 /* DemoCell.swift in Sources */,
Expand Down
17 changes: 17 additions & 0 deletions Example/Agrume Example/AnimatedGifViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Copyright © 2018 Schnaub. All rights reserved.
//

import UIKit
import Agrume
import SwiftyGif

final class AnimatedGifViewController: UIViewController {

@IBAction func openImage(_ sender: Any?) {
let image = UIImage(gifName: "animated.gif")
let agrume = Agrume(image: image, background: .blurred(.regular))
agrume.show(from: self)
}

}
Loading