38 Commits

Author SHA1 Message Date
Khoa Pham 1b16b2bb74 Update podspec 2018-09-27 10:55:35 +02:00
Khoa Pham 32c45514c8 Update demo 2018-09-27 10:51:16 +02:00
Khoa Pham e73f58ced5 Update to Swift 4 2018-09-27 10:47:47 +02:00
Khoa 54b73d3cc0 Merge pull request #206 from fassko/master
Swift 4.2 and Xcode 10
2018-09-27 10:39:35 +02:00
Kristaps Grinbergs 8fc34e8d12 Two issues need to fix for Swift 4.2 2018-09-26 10:18:38 +03:00
Kristaps Grinbergs 6af9321ea9 * Swift 4.2 and Xcode 10
* SwiftLint warnings and errors, added some short variable names in config
* Example project to Swift 4.2 and Xcode 10
* bump version
2018-09-23 13:25:03 +03:00
Khoa 1584281c41 Merge pull request #182 from t0a0/Image_preload_constant
Added possibility to set image preload value
2018-05-16 13:44:04 +02:00
Igor Fedotov 5ac3f8ae18 fixed typo 2018-02-13 19:45:21 +01:00
Igor Fedotov 5d93293649 upd range syntax for consistency 2018-02-13 19:42:53 +01:00
Igor Fedotov a4f113d066 updated lightbox controller to handle preload 2018-02-13 19:37:50 +01:00
Igor Fedotov 41436d8083 This unloads the image when the pageView is stubbed 2018-02-13 19:31:59 +01:00
Igor Fedotov 22785514bd Add variable to config, to allow preload 2018-02-13 18:58:09 +01:00
Igor Fedotov d8f6836c0f forgot to commit xcode files for the stub 2018-02-13 18:57:34 +01:00
Igor Fedotov 20ea9e3e1c Added private init method on LightboxImage to support the stub 2018-02-13 18:56:07 +01:00
Igor Fedotov 64dee3b6bc Added a subclass to stub the images, that do not need to be loaded 2018-02-13 18:55:31 +01:00
Igor Fedotov 911d0c5df8 Made PageView able to update with image 2018-02-13 18:52:33 +01:00
Igor Fedotov cc85786658 Fixed unnecessar call, that was making images to be fetched twice 2018-02-13 17:03:14 +01:00
Vadym Markov 3b695da3ee Merge pull request #181 from t0a0/Support_for_init_with_closure
Added support to init with closure
2018-02-12 23:14:26 +01:00
Igor Fedotov 5a73ca4c6b Added support to init with closure 2018-02-12 22:59:12 +01:00
Khoa Pham 90d31b75ca Bump to 2.1.2 2018-01-02 12:21:59 +01:00
Khoa 9d6d6e3798 Merge pull request #172 from hyperoslo/fix/page
Fix footer frame
2018-01-02 12:11:46 +01:00
Khoa Pham 81e13530aa Set size and origin 2018-01-02 11:45:41 +01:00
Khoa Pham f11af83808 Update dependencies in demo 2018-01-02 11:39:38 +01:00
Christoffer Winterkvist 162f6d29c3 Merge pull request #167 from vincentsaluzzo/master
Carthage compatibility
2017-12-09 20:32:28 +01:00
Vincent Saluzzo cb97450102 remove copy framework build phase which should make only on app building and not framework (nested framework aren't allowed by Apple) 2017-12-08 12:07:09 +01:00
Khoa 9de5f16735 Merge pull request #163 from rinat-enikeev/fix-footer-counter
Fix footer counter
2017-11-27 13:59:07 +01:00
Rinat Enikeev 418da11c82 fix footer counter
reason: you should take into account spacing while calculating current page
2017-11-27 17:45:30 +05:00
Khoa Pham 90fe59ffc6 Bump to 2.1.1 2017-11-21 14:24:34 +01:00
Khoa Pham 422b23b4c2 Update README.md 2017-11-21 10:41:26 +01:00
Khoa Pham 08a4c284f4 Merge pull request #156 from andreyrd/fix/no-window-bounds
Use view.bounds instead of UIApplicationDelegate.window.bounds
2017-11-20 21:59:07 +01:00
Khoa Pham b775f12fe5 Merge pull request #157 from hyperoslo/fix/truncating
Add test
2017-11-20 15:47:17 +01:00
Khoa Pham 9f75ddffdf Use just 1 test 2017-11-20 14:53:21 +01:00
Khoa Pham 225fac033a Remove fileprivate in order to test 2017-11-20 14:49:26 +01:00
Khoa Pham fe3229278d Add test 2017-11-20 14:48:57 +01:00
Khoa Pham de0d273258 Add quotes 2017-11-20 14:26:01 +01:00
Khoa Pham d1231f19ff Fix swiftlint warnings 2017-11-20 14:25:33 +01:00
Khoa Pham 20f927f338 Need to greater than startIndex 2017-11-20 14:22:40 +01:00
Andrey Radchishin 8144d96129 Use view.bounds instead of UIApplicationDelegate.window.bounds 2017-11-17 10:11:20 -08:00
27 changed files with 436 additions and 153 deletions
+1 -1
View File
@@ -1 +1 @@
4.0
4.2
+3
View File
@@ -41,4 +41,7 @@ variable_name:
- id
- URL
- GlobalAPIKey
- i
- lb
- rb
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle)
+1 -2
View File
@@ -1,2 +1 @@
github "hyperoslo/Hue" ~> 3.0
github "hyperoslo/Imaginary" ~> 3.0
github "hyperoslo/Imaginary" ~> 4.0
+2 -3
View File
@@ -1,3 +1,2 @@
github "hyperoslo/Cache" "4.1.2"
github "hyperoslo/Hue" "3.0.0"
github "hyperoslo/Imaginary" "3.0.2"
github "hyperoslo/Cache" "5.2.0"
github "hyperoslo/Imaginary" "4.2.0"
@@ -56,7 +56,9 @@
B1B2B3DADEEC7FD14D4A9FF8 /* Frameworks */,
0C8887567644E86396B8D885 /* Pods */,
);
indentWidth = 4;
sourceTree = "<group>";
tabWidth = 4;
};
29B4A42A1C43A4320060ED52 /* Products */ = {
isa = PBXGroup;
@@ -99,7 +101,6 @@
29B4A4261C43A4320060ED52 /* Frameworks */,
29B4A4271C43A4320060ED52 /* Resources */,
F162948C45248BBD677112BF /* [CP] Embed Pods Frameworks */,
D1AB0C213924D367899FA1A2 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -117,7 +118,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0900;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Hyper Interaktiv AS";
TargetAttributes = {
29B4A4281C43A4320060ED52 = {
@@ -176,45 +177,26 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
D1AB0C213924D367899FA1A2 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DemoLightbox/Pods-DemoLightbox-resources.sh\"\n";
showEnvVarsInLog = 0;
};
F162948C45248BBD677112BF /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-DemoLightbox/Pods-DemoLightbox-frameworks.sh",
"${PODS_ROOT}/Target Support Files/Pods-DemoLightbox/Pods-DemoLightbox-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Cache/Cache.framework",
"${BUILT_PRODUCTS_DIR}/Hue/Hue.framework",
"${BUILT_PRODUCTS_DIR}/Imaginary/Imaginary.framework",
"${BUILT_PRODUCTS_DIR}/Lightbox/Lightbox.framework",
"${BUILT_PRODUCTS_DIR}/SwiftHash/SwiftHash.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cache.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Hue.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Imaginary.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Lightbox.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftHash.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DemoLightbox/Pods-DemoLightbox-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-DemoLightbox/Pods-DemoLightbox-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -255,12 +237,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -292,7 +276,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -308,12 +292,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -338,7 +324,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -7,7 +7,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow()
window?.rootViewController = controller
window?.makeKeyAndVisible()
@@ -6,8 +6,8 @@ class ViewController: UIViewController {
lazy var showButton: UIButton = { [unowned self] in
let button = UIButton()
button.addTarget(self, action: #selector(showLightbox), for: .touchUpInside)
button.setTitle("Show me the lightbox", for: UIControlState())
button.setTitleColor(UIColor(red:0.47, green:0.6, blue:0.13, alpha:1), for: UIControlState())
button.setTitle("Show me the lightbox", for: UIControl.State())
button.setTitleColor(UIColor(red:0.47, green:0.6, blue:0.13, alpha:1), for: UIControl.State())
button.titleLabel?.font = UIFont(name: "AvenirNextCondensed-DemiBold", size: 30)
button.frame = UIScreen.main.bounds
button.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin, .flexibleBottomMargin]
+15 -16
View File
@@ -1,28 +1,27 @@
PODS:
- Cache (4.0.2):
- SwiftHash (~> 2.0.0)
- Hue (3.0.0)
- Imaginary (3.0.0):
- Cache (~> 4.0)
- Lightbox (2.0.0):
- Hue (~> 3.0)
- Imaginary (~> 3.0)
- SwiftHash (2.0.0)
- Cache (5.2.0)
- Imaginary (4.2.0):
- Cache (~> 5.0)
- Lightbox (2.2.0):
- Imaginary (~> 4.0)
DEPENDENCIES:
- Lightbox (from `../../`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- Cache
- Imaginary
EXTERNAL SOURCES:
Lightbox:
:path: ../../
:path: "../../"
SPEC CHECKSUMS:
Cache: 363b6899cee63c82ccbd291e64a6c202abc17a88
Hue: b8fe1e43eef13631331eebecb2198b68e2622f95
Imaginary: 2765d293d425cbed3b07fa11642554cbaebe913d
Lightbox: f7f1cc942d81e84d85095531208f5fe1bfd9c639
SwiftHash: d2e09b13495447178cdfb8e46e54a5c46f15f5a9
Cache: 807c5d86d01a177f06ede9865add3aea269bbfd4
Imaginary: dae33d06dbc2ada22f98afef5eb45cc061311a2c
Lightbox: af4d61903506aa3151a314daa853f7cb3ad39301
PODFILE CHECKSUM: 408ae3477507a1d4b7ff06ffb3f162eda443424f
COCOAPODS: 1.3.1
COCOAPODS: 1.6.0.beta.1
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
+13
View File
@@ -0,0 +1,13 @@
import XCTest
@testable import Lightbox
class InfoLabelTests: XCTestCase {
func testTruncating() {
let label = InfoLabel(text: "", expanded: false)
label.frame.size = CGSize(width: 10, height: 10)
let text = Array(repeating: "A", count: 4).joined(separator: "")
label.fullText = text
_ = label.truncatedText
}
}
+3 -4
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "Lightbox"
s.summary = "A a convenient and easy to use image viewer for your iOS app, packed with all the features you expect"
s.version = "2.1.0"
s.version = "2.3.0"
s.homepage = "https://github.com/hyperoslo/Lightbox"
s.license = 'MIT'
s.author = { "Hyper Interaktiv AS" => "ios@hyper.no" }
@@ -13,8 +13,7 @@ Pod::Spec.new do |s|
s.ios.resource = 'Resources/Lightbox.bundle'
s.frameworks = 'UIKit', 'AVFoundation', 'AVKit'
s.dependency 'Hue', '~> 3.0'
s.dependency 'Imaginary', '~> 3.0'
s.dependency 'Imaginary', '~> 4.0'
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.0' }
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.2' }
end
+148 -40
View File
@@ -7,7 +7,11 @@
objects = {
/* Begin PBXBuildFile section */
166E3BA920333E04006799C1 /* LightboxImageStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 166E3BA820333E04006799C1 /* LightboxImageStub.swift */; };
D22006741DFB4D9700E92898 /* Lightbox.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D22006731DFB4D9700E92898 /* Lightbox.bundle */; };
D2258CC4215CD035005A9A1C /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2258CC3215CD035005A9A1C /* Color+Extensions.swift */; };
D229B5E61FC3123F00F04123 /* Lightbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D523B0A91C43AA2A001AD1EC /* Lightbox.framework */; };
D229B5ED1FC3125D00F04123 /* InfoLabelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D229B5EC1FC3125D00F04123 /* InfoLabelTests.swift */; };
D2A58F5E1F7943A30064F14E /* Imaginary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2A58F5D1F7943A30064F14E /* Imaginary.framework */; };
D2D71BBC1D54DA77006AB907 /* AssetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D71BBB1D54DA77006AB907 /* AssetManager.swift */; };
D5026B3C1C5BF3FD003BC1A3 /* LightboxImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5026B3B1C5BF3FD003BC1A3 /* LightboxImage.swift */; };
@@ -15,7 +19,6 @@
D523B0BE1C43AA8B001AD1EC /* LightboxController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D523B0B71C43AA8A001AD1EC /* LightboxController.swift */; };
D54DFCBE1C5AAAD600ADEA0E /* InfoLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54DFCBC1C5AAAD600ADEA0E /* InfoLabel.swift */; };
D54DFCBF1C5AAAD600ADEA0E /* PageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D54DFCBD1C5AAAD600ADEA0E /* PageView.swift */; };
D54DFCC21C5AAAF100ADEA0E /* Hue.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D54DFCC01C5AAAF100ADEA0E /* Hue.framework */; };
D56F15C81E0AB79800F128AF /* LoadingIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D56F15C71E0AB79800F128AF /* LoadingIndicator.swift */; };
D573A2F01C5B5605006053DD /* HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D573A2EF1C5B5605006053DD /* HeaderView.swift */; };
D573A2F31C5B5C7B006053DD /* LayoutConfigurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D573A2F21C5B5C7B006053DD /* LayoutConfigurable.swift */; };
@@ -24,8 +27,23 @@
D58A18CB1C5ABF8F000024BB /* FooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58A18CA1C5ABF8F000024BB /* FooterView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
D229B5E71FC3123F00F04123 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D523B0A01C43AA2A001AD1EC /* Project object */;
proxyType = 1;
remoteGlobalIDString = D523B0A81C43AA2A001AD1EC;
remoteInfo = "Lightbox-iOS";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
166E3BA820333E04006799C1 /* LightboxImageStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LightboxImageStub.swift; sourceTree = "<group>"; };
D22006731DFB4D9700E92898 /* Lightbox.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Lightbox.bundle; sourceTree = "<group>"; };
D2258CC3215CD035005A9A1C /* Color+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extensions.swift"; sourceTree = "<group>"; };
D229B5E11FC3123F00F04123 /* Lightbox-iOS-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Lightbox-iOS-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
D229B5E51FC3123F00F04123 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D229B5EC1FC3125D00F04123 /* InfoLabelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoLabelTests.swift; sourceTree = "<group>"; };
D2A58F5D1F7943A30064F14E /* Imaginary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Imaginary.framework; path = Carthage/Build/iOS/Imaginary.framework; sourceTree = "<group>"; };
D2D71BBB1D54DA77006AB907 /* AssetManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssetManager.swift; sourceTree = "<group>"; };
D5026B3B1C5BF3FD003BC1A3 /* LightboxImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LightboxImage.swift; sourceTree = "<group>"; };
@@ -45,12 +63,19 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
D229B5DE1FC3123F00F04123 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D229B5E61FC3123F00F04123 /* Lightbox.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D523B0A51C43AA2A001AD1EC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D2A58F5E1F7943A30064F14E /* Imaginary.framework in Frameworks */,
D54DFCC21C5AAAF100ADEA0E /* Hue.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -65,6 +90,15 @@
path = Resources;
sourceTree = "<group>";
};
D229B5E21FC3123F00F04123 /* Lightbox-iOS-Tests */ = {
isa = PBXGroup;
children = (
D229B5E51FC3123F00F04123 /* Info.plist */,
D229B5EC1FC3125D00F04123 /* InfoLabelTests.swift */,
);
path = "Lightbox-iOS-Tests";
sourceTree = "<group>";
};
D2A58F5C1F7943A30064F14E /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -80,15 +114,19 @@
D54DFCC01C5AAAF100ADEA0E /* Hue.framework */,
D523B0B41C43AA8A001AD1EC /* Source */,
D523B0AB1C43AA2A001AD1EC /* Lightbox */,
D229B5E21FC3123F00F04123 /* Lightbox-iOS-Tests */,
D523B0AA1C43AA2A001AD1EC /* Products */,
D2A58F5C1F7943A30064F14E /* Frameworks */,
);
indentWidth = 4;
sourceTree = "<group>";
tabWidth = 4;
};
D523B0AA1C43AA2A001AD1EC /* Products */ = {
isa = PBXGroup;
children = (
D523B0A91C43AA2A001AD1EC /* Lightbox.framework */,
D229B5E11FC3123F00F04123 /* Lightbox-iOS-Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -109,6 +147,7 @@
D523B0B61C43AA8A001AD1EC /* LightboxConfig.swift */,
D523B0B71C43AA8A001AD1EC /* LightboxController.swift */,
D5026B3B1C5BF3FD003BC1A3 /* LightboxImage.swift */,
166E3BA820333E04006799C1 /* LightboxImageStub.swift */,
D2D71BBB1D54DA77006AB907 /* AssetManager.swift */,
);
path = Source;
@@ -132,6 +171,7 @@
D573A2F41C5B5CA4006053DD /* LightboxTransition.swift */,
D573A2F21C5B5C7B006053DD /* LayoutConfigurable.swift */,
D573A2F61C5B5E55006053DD /* UIView+Gradient.swift */,
D2258CC3215CD035005A9A1C /* Color+Extensions.swift */,
);
path = Library;
sourceTree = "<group>";
@@ -149,6 +189,24 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
D229B5E01FC3123F00F04123 /* Lightbox-iOS-Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = D229B5E91FC3123F00F04123 /* Build configuration list for PBXNativeTarget "Lightbox-iOS-Tests" */;
buildPhases = (
D229B5DD1FC3123F00F04123 /* Sources */,
D229B5DE1FC3123F00F04123 /* Frameworks */,
D229B5DF1FC3123F00F04123 /* Resources */,
);
buildRules = (
);
dependencies = (
D229B5E81FC3123F00F04123 /* PBXTargetDependency */,
);
name = "Lightbox-iOS-Tests";
productName = "Lightbox-iOS-Tests";
productReference = D229B5E11FC3123F00F04123 /* Lightbox-iOS-Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
D523B0A81C43AA2A001AD1EC /* Lightbox-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = D523B0B11C43AA2A001AD1EC /* Build configuration list for PBXNativeTarget "Lightbox-iOS" */;
@@ -157,8 +215,6 @@
D523B0A51C43AA2A001AD1EC /* Frameworks */,
D523B0A61C43AA2A001AD1EC /* Headers */,
D523B0A71C43AA2A001AD1EC /* Resources */,
D54DFCC41C5AAAF600ADEA0E /* Copy frameworks with Carthage */,
5CF8A88D1F50B4EA00C28475 /* ShellScript */,
);
buildRules = (
);
@@ -175,9 +231,14 @@
D523B0A01C43AA2A001AD1EC /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0900;
LastSwiftUpdateCheck = 0910;
LastUpgradeCheck = 1000;
ORGANIZATIONNAME = "Hyper Interaktiv AS";
TargetAttributes = {
D229B5E01FC3123F00F04123 = {
CreatedOnToolsVersion = 9.1;
ProvisioningStyle = Automatic;
};
D523B0A81C43AA2A001AD1EC = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0900;
@@ -197,11 +258,19 @@
projectRoot = "";
targets = (
D523B0A81C43AA2A001AD1EC /* Lightbox-iOS */,
D229B5E01FC3123F00F04123 /* Lightbox-iOS-Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
D229B5DF1FC3123F00F04123 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D523B0A71C43AA2A001AD1EC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -212,40 +281,15 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
5CF8A88D1F50B4EA00C28475 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
};
D54DFCC41C5AAAF600ADEA0E /* Copy frameworks with Carthage */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/Carthage/Build/iOS/Hue.framework",
"$(SRCROOT)/Carthage/Build/iOS/Imaginary.framework",
"$(SRCROOT)/Carthage/Build/iOS/Cache.framework",
);
name = "Copy frameworks with Carthage";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/local/bin/carthage copy-frameworks";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
D229B5DD1FC3123F00F04123 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D229B5ED1FC3125D00F04123 /* InfoLabelTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D523B0A41C43AA2A001AD1EC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -261,13 +305,64 @@
D58A18CB1C5ABF8F000024BB /* FooterView.swift in Sources */,
D573A2F01C5B5605006053DD /* HeaderView.swift in Sources */,
D573A2F51C5B5CA4006053DD /* LightboxTransition.swift in Sources */,
D2258CC4215CD035005A9A1C /* Color+Extensions.swift in Sources */,
166E3BA920333E04006799C1 /* LightboxImageStub.swift in Sources */,
D2D71BBC1D54DA77006AB907 /* AssetManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
D229B5E81FC3123F00F04123 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D523B0A81C43AA2A001AD1EC /* Lightbox-iOS */;
targetProxy = D229B5E71FC3123F00F04123 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
D229B5EA1FC3123F00F04123 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "Lightbox-iOS-Tests/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.fantageek.Lightbox-iOS-Tests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
D229B5EB1FC3123F00F04123 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "Lightbox-iOS-Tests/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 11.1;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.fantageek.Lightbox-iOS-Tests";
PRODUCT_NAME = "$(TARGET_NAME)";
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
D523B0AF1C43AA2A001AD1EC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -280,12 +375,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -318,7 +415,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -337,12 +434,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -368,7 +467,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@@ -423,6 +522,15 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
D229B5E91FC3123F00F04123 /* Build configuration list for PBXNativeTarget "Lightbox-iOS-Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D229B5EA1FC3123F00F04123 /* Debug */,
D229B5EB1FC3123F00F04123 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D523B0A31C43AA2A001AD1EC /* Build configuration list for PBXProject "Lightbox" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0900"
LastUpgradeVersion = "1000"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -26,10 +26,30 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES"
testExecutionOrdering = "random">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D229B5E01FC3123F00F04123"
BuildableName = "Lightbox-iOS-Tests.xctest"
BlueprintName = "Lightbox-iOS-Tests"
ReferencedContainer = "container:Lightbox.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D523B0A81C43AA2A001AD1EC"
BuildableName = "Lightbox.framework"
BlueprintName = "Lightbox-iOS"
ReferencedContainer = "container:Lightbox.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
@@ -37,7 +57,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
+1 -1
View File
@@ -110,7 +110,7 @@ extension ViewController: LightboxControllerDismissalDelegate: class {
### Image loading
By default images are loaded using [Imagary](https://github.com/hyperoslo/Imaginary) for reliable loading and caching. But it's easy to change this behavior using **LightboxConfig**
By default images are loaded using [Imaginary](https://github.com/hyperoslo/Imaginary) for reliable loading and caching. But it's easy to change this behavior using **LightboxConfig**
```swift
LightboxConfig.loadImage = {
+27
View File
@@ -0,0 +1,27 @@
import UIKit
public extension UIColor {
/// Constructing color from hex string
///
/// - Parameter hex: A hex string, can either contain # or not
convenience init(hex string: String) {
var hex = string.hasPrefix("#")
? String(string.dropFirst())
: string
guard hex.count == 3 || hex.count == 6
else {
self.init(white: 1.0, alpha: 0.0)
return
}
if hex.count == 3 {
for (index, char) in hex.enumerated() {
hex.insert(char, at: hex.index(hex.startIndex, offsetBy: index * 2))
}
}
self.init(
red: CGFloat((Int(hex, radix: 16)! >> 16) & 0xFF) / 255.0,
green: CGFloat((Int(hex, radix: 16)! >> 8) & 0xFF) / 255.0,
blue: CGFloat((Int(hex, radix: 16)!) & 0xFF) / 255.0, alpha: 1.0)
}
}
+1 -1
View File
@@ -163,7 +163,7 @@ extension LightboxTransition: UIGestureRecognizerDelegate {
if let panGestureRecognizer = gestureRecognizer as? UIPanGestureRecognizer {
let translation = panGestureRecognizer.translation(in: gestureRecognizer.view)
if fabs(translation.x) < fabs(translation.y) {
if abs(translation.x) < abs(translation.y) {
result = true
}
}
+10 -7
View File
@@ -1,5 +1,4 @@
import UIKit
import Hue
import AVKit
import AVFoundation
import Imaginary
@@ -19,8 +18,7 @@ public class LightboxConfig {
}
/// How to load image onto UIImageView
public static var loadImage: (UIImageView, URL, ((UIImage?) -> Void)?) -> Void =
{ (imageView, imageURL , completion) in
public static var loadImage: (UIImageView, URL, ((UIImage?) -> Void)?) -> Void = { (imageView, imageURL, completion) in
// Use Imaginary by default
imageView.setImage(url: imageURL, placeholder: nil, completion: { result in
@@ -38,11 +36,16 @@ public class LightboxConfig {
return LoadingIndicator()
}
/// Number of images to preload.
///
/// 0 - Preload all images (default).
public static var preload = 0
public struct PageIndicator {
public static var enabled = true
public static var separatorColor = UIColor(hex: "3D4757")
public static var textAttributes: [NSAttributedStringKey: Any] = [
public static var textAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor(hex: "899AB8"),
.paragraphStyle: {
@@ -59,7 +62,7 @@ public class LightboxConfig {
public static var text = NSLocalizedString("Close", comment: "")
public static var image: UIImage?
public static var textAttributes: [NSAttributedStringKey: Any] = [
public static var textAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.boldSystemFont(ofSize: 16),
.foregroundColor: UIColor.white,
.paragraphStyle: {
@@ -76,7 +79,7 @@ public class LightboxConfig {
public static var text = NSLocalizedString("Delete", comment: "")
public static var image: UIImage?
public static var textAttributes: [NSAttributedStringKey: Any] = [
public static var textAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.boldSystemFont(ofSize: 16),
.foregroundColor: UIColor(hex: "FA2F5B"),
.paragraphStyle: {
@@ -93,7 +96,7 @@ public class LightboxConfig {
public static var ellipsisText = NSLocalizedString("Show more", comment: "")
public static var ellipsisColor = UIColor(hex: "899AB9")
public static var textAttributes: [NSAttributedStringKey: Any] = [
public static var textAttributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 12),
.foregroundColor: UIColor(hex: "DBDBDB")
]
+57 -18
View File
@@ -1,5 +1,4 @@
import UIKit
import Hue
public protocol LightboxControllerPageDelegate: class {
@@ -25,7 +24,7 @@ open class LightboxController: UIViewController {
scrollView.isPagingEnabled = false
scrollView.delegate = self
scrollView.showsHorizontalScrollIndicator = false
scrollView.decelerationRate = UIScrollViewDecelerationRateFast
scrollView.decelerationRate = UIScrollView.DecelerationRate.fast
return scrollView
}()
@@ -71,7 +70,7 @@ open class LightboxController: UIViewController {
open fileprivate(set) lazy var overlayView: UIView = { [unowned self] in
let view = UIView(frame: CGRect.zero)
let gradient = CAGradientLayer()
let colors = [UIColor(hex: "090909").alpha(0), UIColor(hex: "040404")]
let colors = [UIColor(hex: "090909").withAlphaComponent(0), UIColor(hex: "040404")]
view.addGradientLayer(colors)
view.alpha = 0
@@ -91,6 +90,8 @@ open class LightboxController: UIViewController {
seen = true
}
reconfigurePagesForPreload()
pageDelegate?.lightboxController(self, didMoveToPage: currentPage)
if let image = pageViews[currentPage].imageView.image, dynamicBackground {
@@ -121,7 +122,7 @@ open class LightboxController: UIViewController {
open var spacing: CGFloat = 20 {
didSet {
configureLayout()
configureLayout(view.bounds.size)
}
}
@@ -130,6 +131,7 @@ open class LightboxController: UIViewController {
return pageViews.map { $0.image }
}
set(value) {
initialImages = value
configurePages(value)
}
}
@@ -144,7 +146,7 @@ open class LightboxController: UIViewController {
var pageViews = [PageView]()
var statusBarHidden = false
fileprivate let initialImages: [LightboxImage]
fileprivate var initialImages: [LightboxImage]
fileprivate let initialPage: Int
// MARK: - Initializers
@@ -175,16 +177,15 @@ open class LightboxController: UIViewController {
overlayView.addGestureRecognizer(overlayTapGestureRecognizer)
configurePages(initialImages)
currentPage = initialPage
goTo(currentPage, animated: false)
goTo(initialPage, animated: false)
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !presented {
presented = true
configureLayout()
configureLayout(view.bounds.size)
}
}
@@ -192,13 +193,16 @@ open class LightboxController: UIViewController {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
footerView.frame = CGRect(
x: 0,
y: view.bounds.height - footerView.frame.height,
footerView.frame.size = CGSize(
width: view.bounds.width,
height: 100
)
footerView.frame.origin = CGPoint(
x: 0,
y: view.bounds.height - footerView.frame.height
)
headerView.frame = CGRect(
x: 0,
y: 16,
@@ -227,15 +231,34 @@ open class LightboxController: UIViewController {
pageViews.forEach { $0.removeFromSuperview() }
pageViews = []
for image in images {
let pageView = PageView(image: image)
let preloadIndicies = calculatePreloadIndicies()
for i in 0..<images.count {
let pageView = PageView(image: preloadIndicies.contains(i) ? images[i] : LightboxImageStub())
pageView.pageViewDelegate = self
scrollView.addSubview(pageView)
pageViews.append(pageView)
}
configureLayout()
configureLayout(view.bounds.size)
}
func reconfigurePagesForPreload() {
let preloadIndicies = calculatePreloadIndicies()
for i in 0..<initialImages.count {
let pageView = pageViews[i]
if preloadIndicies.contains(i) {
if type(of: pageView.image) == LightboxImageStub.self {
pageView.update(with: initialImages[i])
}
} else {
if type(of: pageView.image) != LightboxImageStub.self {
pageView.update(with: LightboxImageStub())
}
}
}
}
// MARK: - Pagination
@@ -271,7 +294,7 @@ open class LightboxController: UIViewController {
// MARK: - Layout
open func configureLayout(_ size: CGSize = UIApplication.shared.delegate?.window??.bounds.size ?? .zero) {
open func configureLayout(_ size: CGSize) {
scrollView.frame.size = size
scrollView.contentSize = CGSize(
width: size.width * CGFloat(numberOfPages) + spacing * CGFloat(numberOfPages - 1),
@@ -296,7 +319,7 @@ open class LightboxController: UIViewController {
fileprivate func loadDynamicBackground(_ image: UIImage) {
backgroundView.image = image
backgroundView.layer.add(CATransition(), forKey: kCATransitionFade)
backgroundView.layer.add(CATransition(), forKey: "fade")
}
func toggleControls(pageView: PageView?, visible: Bool, duration: TimeInterval = 0.1, delay: TimeInterval = 0) {
@@ -310,6 +333,22 @@ open class LightboxController: UIViewController {
pageView?.playButton.alpha = alpha
}, completion: nil)
}
// MARK: - Helper functions
func calculatePreloadIndicies () -> [Int] {
var preloadIndicies: [Int] = []
let preload = LightboxConfig.preload
if preload > 0 {
let lb = max(0, currentPage - preload)
let rb = min(initialImages.count, currentPage + preload)
for i in lb..<rb {
preloadIndicies.append(i)
}
} else {
preloadIndicies = [Int](0..<initialImages.count)
}
return preloadIndicies
}
}
// MARK: - UIScrollViewDelegate
@@ -335,7 +374,7 @@ extension LightboxController: UIScrollViewDelegate {
}
targetContentOffset.pointee.x = x
currentPage = Int(x / view.bounds.width)
currentPage = Int(x / pageWidth)
}
}
@@ -400,7 +439,7 @@ extension LightboxController: HeaderViewDelegate {
self.pageViews.remove(at: prevIndex).removeFromSuperview()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
self.configureLayout()
self.configureLayout(self.view.bounds.size)
self.currentPage = Int(self.scrollView.contentOffset.x / self.view.bounds.width)
deleteButton.isEnabled = true
}
+18
View File
@@ -6,10 +6,15 @@ open class LightboxImage {
open fileprivate(set) var image: UIImage?
open fileprivate(set) var imageURL: URL?
open fileprivate(set) var videoURL: URL?
open fileprivate(set) var imageClosure: (() -> UIImage)?
open var text: String
// MARK: - Initialization
internal init(text: String = "") {
self.text = text
}
public init(image: UIImage, text: String = "", videoURL: URL? = nil) {
self.image = image
self.text = text
@@ -22,12 +27,25 @@ open class LightboxImage {
self.videoURL = videoURL
}
public init(imageClosure: @escaping () -> UIImage, text: String = "", videoURL: URL? = nil) {
self.imageClosure = imageClosure
self.text = text
self.videoURL = videoURL
}
open func addImageTo(_ imageView: UIImageView, completion: ((UIImage?) -> Void)? = nil) {
if let image = image {
imageView.image = image
completion?(image)
} else if let imageURL = imageURL {
LightboxConfig.loadImage(imageView, imageURL, completion)
} else if let imageClosure = imageClosure {
let img = imageClosure()
imageView.image = img
completion?(img)
} else {
imageView.image = nil
completion?(nil)
}
}
}
+10
View File
@@ -0,0 +1,10 @@
import UIKit
internal class LightboxImageStub: LightboxImage {
// MARK: - Initialization
init () {
super.init()
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ open class FooterView: UIView {
return view
}()
let gradientColors = [UIColor(hex: "040404").alpha(0.1), UIColor(hex: "040404")]
let gradientColors = [UIColor(hex: "040404").withAlphaComponent(0.1), UIColor(hex: "040404")]
open weak var delegate: FooterViewDelegate?
// MARK: - Initializers
+4 -4
View File
@@ -13,7 +13,7 @@ open class HeaderView: UIView {
let button = UIButton(type: .system)
button.setAttributedTitle(title, for: UIControlState())
button.setAttributedTitle(title, for: UIControl.State())
if let size = LightboxConfig.CloseButton.size {
button.frame.size = size
@@ -25,7 +25,7 @@ open class HeaderView: UIView {
for: .touchUpInside)
if let image = LightboxConfig.CloseButton.image {
button.setBackgroundImage(image, for: UIControlState())
button.setBackgroundImage(image, for: UIControl.State())
}
button.isHidden = !LightboxConfig.CloseButton.enabled
@@ -52,7 +52,7 @@ open class HeaderView: UIView {
for: .touchUpInside)
if let image = LightboxConfig.DeleteButton.image {
button.setBackgroundImage(image, for: UIControlState())
button.setBackgroundImage(image, for: UIControl.State())
}
button.isHidden = !LightboxConfig.DeleteButton.enabled
@@ -104,7 +104,7 @@ extension HeaderView: LayoutConfigurable {
x: bounds.width - closeButton.frame.width - 17,
y: topPadding
)
deleteButton.frame.origin = CGPoint(
x: 17,
y: topPadding
+10 -5
View File
@@ -41,7 +41,7 @@ open class InfoLabel: UILabel {
}
}
fileprivate var truncatedText: String {
var truncatedText: String {
var truncatedText = fullText
guard numberOfLines(fullText) > numberOfVisibleLines else {
@@ -60,8 +60,13 @@ open class InfoLabel: UILabel {
// Remove characters ahead of ellipsis until the text is the right number of lines
while numberOfLines(truncatedText) > numberOfVisibleLines {
truncatedTextCursor = truncatedText.index(before: truncatedTextCursor)
truncatedText.remove(at: truncatedTextCursor)
// To avoid "Cannot decrement before startIndex"
guard truncatedTextCursor > truncatedText.startIndex else {
break
}
truncatedTextCursor = truncatedText.index(before: truncatedTextCursor)
truncatedText.remove(at: truncatedTextCursor)
}
return truncatedText
@@ -124,12 +129,12 @@ open class InfoLabel: UILabel {
return string.boundingRect(
with: CGSize(width: bounds.size.width, height: CGFloat.greatestFiniteMagnitude),
options: [.usesLineFragmentOrigin, .usesFontLeading],
attributes: [NSAttributedStringKey.font: font],
attributes: [NSAttributedString.Key.font: font],
context: nil).height
}
fileprivate func numberOfLines(_ string: String) -> Int {
let lineHeight = "A".size(withAttributes: [NSAttributedStringKey.font: font]).height
let lineHeight = "A".size(withAttributes: [NSAttributedString.Key.font: font]).height
let totalHeight = heightForString(string)
return Int(totalHeight / lineHeight)
+1 -1
View File
@@ -13,7 +13,7 @@ class LoadingIndicator: UIView {
alpha = 0
indicator = UIActivityIndicatorView()
indicator.activityIndicatorViewStyle = .whiteLarge
indicator.style = .whiteLarge
indicator.startAnimating()
addSubview(indicator)
+36 -18
View File
@@ -22,7 +22,7 @@ class PageView: UIScrollView {
lazy var playButton: UIButton = {
let button = UIButton(type: .custom)
button.frame.size = CGSize(width: 60, height: 60)
button.setBackgroundImage(AssetManager.image("lightbox_play"), for: UIControlState())
button.setBackgroundImage(AssetManager.image("lightbox_play"), for: UIControl.State())
button.addTarget(self, action: #selector(playButtonTouched(_:)), for: .touchUpInside)
button.layer.shadowOffset = CGSize(width: 1, height: 1)
@@ -51,20 +51,7 @@ class PageView: UIScrollView {
configure()
loadingIndicator.alpha = 1
self.image.addImageTo(imageView) { [weak self] image in
guard let strongSelf = self else {
return
}
strongSelf.isUserInteractionEnabled = true
strongSelf.configureImageView()
strongSelf.pageViewDelegate?.remoteImageDidLoad(image, imageView: strongSelf.imageView)
UIView.animate(withDuration: 0.4) {
strongSelf.loadingIndicator.alpha = 0
}
}
fetchImage()
}
required init?(coder aDecoder: NSCoder) {
@@ -76,9 +63,7 @@ class PageView: UIScrollView {
func configure() {
addSubview(imageView)
if image.videoURL != nil {
addSubview(playButton)
}
updatePlayButton()
addSubview(loadingIndicator)
@@ -100,6 +85,39 @@ class PageView: UIScrollView {
tapRecognizer.require(toFail: doubleTapRecognizer)
}
// MARK: - Update
func update(with image: LightboxImage) {
self.image = image
updatePlayButton()
fetchImage()
}
func updatePlayButton () {
if self.image.videoURL != nil && !subviews.contains(playButton) {
addSubview(playButton)
} else if self.image.videoURL == nil && subviews.contains(playButton) {
playButton.removeFromSuperview()
}
}
// MARK: - Fetch
private func fetchImage () {
loadingIndicator.alpha = 1
self.image.addImageTo(imageView) { [weak self] image in
guard let self = self else {
return
}
self.isUserInteractionEnabled = true
self.configureImageView()
self.pageViewDelegate?.remoteImageDidLoad(image, imageView: self.imageView)
UIView.animate(withDuration: 0.4) {
self.loadingIndicator.alpha = 0
}
}
}
// MARK: - Recognizers
@objc func scrollViewDoubleTapped(_ recognizer: UITapGestureRecognizer) {