36 Commits

Author SHA1 Message Date
Elvis Nunez c73d8292b5 Merge pull request #303 from kitwtnb/fix-build-error-for-main-actor-isolation
Fix build error for MainActor isolation.
2024-08-27 13:36:10 +02:00
Keita Watanabe de59c814c6 fix build error for MainActor isolation 2024-08-12 14:40:35 +09:00
Elvis Nunez f588347f58 Merge pull request #301 from kitwtnb/fix-existential-any
Fix existential-any for Swift6
2024-07-29 18:12:28 +02:00
Keita Watanabe dea5e8a4bd fix existential any 2024-07-15 16:27:21 +09:00
Elvis 398ee143f0 Merge pull request #295 from novr/fix_compiler_warning_class
fix: 'class' keyword to define a class-constrained protocol is deprecated
2022-12-21 06:39:24 +01:00
novr b7166be79f fix: 'class' keyword to define a class-constrained protocol is deprecated 2022-12-21 10:38:42 +09:00
Elvis 0119309a25 Merge pull request #287 from kitwtnb/remove-dependency-on-specific-image-request-library
Remove dependencies on specific image request library
2022-12-04 22:35:24 +01:00
Elvis 2ac28e0497 Merge pull request #291 from dknchris/expose-background
Expose image background color via LightboxConfig
2022-10-09 09:36:14 +02:00
Elvis 44c91b41c6 Merge pull request #293 from dknchris/tap-delegate
Add tap delegate for tap/double tap detection
2022-10-09 09:35:52 +02:00
Dicken Christian 619cbba91e Add tap delegate for tap/double tap detection
A reliable tap event helps users hide/unhide navigation bar or toolbars to give a full unobstructed view of the image.
2022-10-02 18:39:58 +05:30
Dicken Christian 2fbb4ba5af Expose image background color via LightboxConfig
This gives users the ability to use a custom background color using LightboxConfig.imageBackgroundColor
2022-10-02 15:39:14 +05:30
Elvis 9cc8c1972d Merge pull request #290 from MohammadRezaAnsari/master
Fixed SPM resolving issue
2022-09-13 23:55:09 +02:00
Mohammad Reza Ansary 88b08b262d Merge pull request #1 from MohammadRezaAnsari/hotFix
Remove Imaginary framework dependency
2022-09-11 14:49:23 +04:30
Mohammad Reza Ansary a3825a081a Remove Imaginary framework dependency 2022-09-11 14:45:41 +04:30
Elvis 63004497df Merge pull request #289 from alexstich/prod
Image deleting delegate
2022-08-18 20:58:10 +02:00
AlexStich daca12b64a Add LightboxControllerDeleteDelegate to have delegate for image deleting action 2022-08-03 22:44:56 +04:00
Keita Watanabe 3ac333b6a8 remove dependency on SDWebImage 2022-06-23 10:55:36 +09:00
Elvis 64573991e0 Merge pull request #283 from Saturn-Technologies/master
Using SDWedImage instead Imginery for caching
2022-02-10 14:49:23 +01:00
Steven Guo 7e06642187 update Podspec 2022-02-07 14:09:46 -05:00
Steven Guo 256610707e switch to SDWebImage from Imaginery and use the SDAnimatedGifView 2022-02-07 12:50:05 -05:00
E L V I S a07de07adb Merge pull request #267 from davidevincenzi/master
Move configureLayout(_) in viewDidLayoutSubviews()
2020-11-18 20:11:36 +01:00
Davide fbd246db01 Move configureLayout(_) in viewDidLayoutSubviews() 2020-11-01 09:26:18 +01:00
E L V I S 7b1b9370ab Merge pull request #265 from alexandrgl/delete-button-crash-fix
Fix app crash when tap delete button.
2020-10-30 06:16:29 +01:00
Aleksandr Glushchenko 502f9a6f92 Update LightboxController.swift 2020-10-29 19:55:16 +02:00
E L V I S 2cac1cf4b2 Update Lightbox.podspec 2020-10-04 08:41:44 +02:00
E L V I S 918918649c Merge pull request #264 from hyperoslo/update-project
Update project
2020-10-04 08:41:12 +02:00
Elvis e36c794651 Update projects 2020-10-04 08:40:54 +02:00
Elvis 1f42c0229c Update project 2020-10-04 08:17:54 +02:00
E L V I S 6f0ead5af5 Update Lightbox.podspec 2020-07-09 19:47:10 -05:00
E L V I S 4a70c08f37 Merge pull request #254 from hyperoslo/force-modalPresentationStyle
Force modal presentation style
2020-07-09 19:46:46 -05:00
Elvis 7830a7512a Add comment 2020-07-09 19:45:55 -05:00
Elvis 2bb85661b1 Force usage of modalPresentationStyle 2020-07-09 19:44:03 -05:00
Elvis dbffe4f688 Update demo to fix broken link and to show label bug 2020-06-22 08:29:04 -05:00
Elvis ed69a9fdee Add navigation controller to demo 2020-06-22 08:22:00 -05:00
E L V I S 6344062be2 Update Lightbox.podspec 2020-06-22 08:17:15 -05:00
Elvis 8dcf50b722 Add backup symbol for play button 2020-06-22 08:16:07 -05:00
18 changed files with 214 additions and 117 deletions
+2 -2
View File
@@ -1,2 +1,2 @@
github "hyperoslo/Imaginary" ~> 4.3
github "hyperoslo/Cache" ~> 5.3
github "hyperoslo/Imaginary" ~> 5.0.0
github "hyperoslo/Cache" ~> 6.0.0
+2 -2
View File
@@ -1,2 +1,2 @@
github "hyperoslo/Cache" "5.3.0"
github "hyperoslo/Imaginary" "4.3.1"
github "hyperoslo/Cache" "6.0.0"
github "hyperoslo/Imaginary" "5.0.0"
+2 -3
View File
@@ -1,19 +1,18 @@
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.4.0"
s.version = "2.5.0"
s.homepage = "https://github.com/hyperoslo/Lightbox"
s.license = 'MIT'
s.author = { "Hyper Interaktiv AS" => "ios@hyper.no" }
s.source = { :git => "https://github.com/hyperoslo/Lightbox.git", :tag => s.version.to_s }
s.social_media_url = 'https://twitter.com/hyperoslo'
s.platform = :ios, '9.0'
s.platform = :ios, '11.0'
s.requires_arc = true
s.source_files = 'Source/**/*'
s.ios.resource = 'Resources/Lightbox.bundle'
s.frameworks = 'UIKit', 'AVFoundation', 'AVKit'
s.dependency 'Imaginary', '~> 4.3.1'
s.swift_version = '5.0'
end
+63 -23
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 52;
objects = {
/* Begin PBXBuildFile section */
@@ -14,11 +14,9 @@
44E6A65C2495BFD400543CF0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44E6A65B2495BFD400543CF0 /* ViewController.swift */; };
44E6A6652495C0EB00543CF0 /* Lightbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D523B0A91C43AA2A001AD1EC /* Lightbox.framework */; };
44E6A6662495C0EB00543CF0 /* Lightbox.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D523B0A91C43AA2A001AD1EC /* Lightbox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
44E6A66A2495C13F00543CF0 /* Imaginary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2A58F5D1F7943A30064F14E /* Imaginary.framework */; };
44E6A66B2495C13F00543CF0 /* Imaginary.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D2A58F5D1F7943A30064F14E /* Imaginary.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
85CB007027B16C6900A47BB3 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = 85CB006F27B16C6900A47BB3 /* SDWebImage */; };
D22006741DFB4D9700E92898 /* Lightbox.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D22006731DFB4D9700E92898 /* Lightbox.bundle */; };
D2258CC4215CD035005A9A1C /* Color+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2258CC3215CD035005A9A1C /* Color+Extensions.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 */; };
D523B0BD1C43AA8B001AD1EC /* LightboxConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = D523B0B61C43AA8A001AD1EC /* LightboxConfig.swift */; };
@@ -50,7 +48,6 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
44E6A66B2495C13F00543CF0 /* Imaginary.framework in Embed Frameworks */,
44E6A6662495C0EB00543CF0 /* Lightbox.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
@@ -68,7 +65,6 @@
44E6A65B2495BFD400543CF0 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.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>"; };
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>"; };
D523B0A91C43AA2A001AD1EC /* Lightbox.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Lightbox.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -90,7 +86,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
44E6A66A2495C13F00543CF0 /* Imaginary.framework in Frameworks */,
44E6A6652495C0EB00543CF0 /* Lightbox.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -99,7 +94,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D2A58F5E1F7943A30064F14E /* Imaginary.framework in Frameworks */,
85CB007027B16C6900A47BB3 /* SDWebImage in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -129,7 +124,6 @@
D2A58F5C1F7943A30064F14E /* Frameworks */ = {
isa = PBXGroup;
children = (
D2A58F5D1F7943A30064F14E /* Imaginary.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -248,6 +242,9 @@
dependencies = (
);
name = "Lightbox-iOS";
packageProductDependencies = (
85CB006F27B16C6900A47BB3 /* SDWebImage */,
);
productName = Lightbox;
productReference = D523B0A91C43AA2A001AD1EC /* Lightbox.framework */;
productType = "com.apple.product-type.framework";
@@ -259,7 +256,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1150;
LastUpgradeCheck = 1150;
LastUpgradeCheck = 1320;
ORGANIZATIONNAME = "Hyper Interaktiv AS";
TargetAttributes = {
44E6A6462495BFAB00543CF0 = {
@@ -281,6 +278,9 @@
Base,
);
mainGroup = D523B09F1C43AA2A001AD1EC;
packageReferences = (
85CB006E27B16C6900A47BB3 /* XCRemoteSwiftPackageReference "SDWebImage" */,
);
productRefGroup = D523B0AA1C43AA2A001AD1EC /* Products */;
projectDirPath = "";
projectRoot = "";
@@ -381,8 +381,11 @@
);
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = iOSDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.5;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.elvisnunez.iOSDemo;
@@ -410,8 +413,11 @@
);
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = iOSDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.5;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.elvisnunez.iOSDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -443,6 +449,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -468,12 +475,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.2;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -503,6 +510,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -522,11 +530,12 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.2;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@@ -548,12 +557,18 @@
);
INFOPLIST_FILE = Lightbox/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Lightbox;
PRODUCT_NAME = Lightbox;
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@@ -571,12 +586,18 @@
);
INFOPLIST_FILE = Lightbox/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Lightbox;
PRODUCT_NAME = Lightbox;
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
@@ -611,6 +632,25 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
85CB006E27B16C6900A47BB3 /* XCRemoteSwiftPackageReference "SDWebImage" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SDWebImage/SDWebImage.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 5.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
85CB006F27B16C6900A47BB3 /* SDWebImage */ = {
isa = XCSwiftPackageProductDependency;
package = 85CB006E27B16C6900A47BB3 /* XCRemoteSwiftPackageReference "SDWebImage" */;
productName = SDWebImage;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = D523B0A01C43AA2A001AD1EC /* Project object */;
}
@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "self:Lightbox.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1150"
LastUpgradeVersion = "1320"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
+2 -4
View File
@@ -8,13 +8,11 @@ let package = Package(
name: "Lightbox",
targets: ["Lightbox"]),
],
dependencies: [
.package(url: "https://github.com/hyperoslo/Imaginary", .branch("master"))
],
dependencies: [],
targets: [
.target(
name: "Lightbox",
dependencies: ["Imaginary"],
dependencies: [],
path: "Source"
)
],
+2 -2
View File
@@ -1,4 +1,4 @@
protocol LayoutConfigurable: class {
protocol LayoutConfigurable: AnyObject {
@MainActor
func configureLayout()
}
+6 -6
View File
@@ -96,11 +96,11 @@ class LightboxTransition: UIPercentDrivenInteractiveTransition {
extension LightboxTransition: UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
func transitionDuration(using transitionContext: (any UIViewControllerContextTransitioning)?) -> TimeInterval {
return 0.25
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
func animateTransition(using transitionContext: any UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
guard let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from),
@@ -133,23 +133,23 @@ extension LightboxTransition: UIViewControllerAnimatedTransitioning {
extension LightboxTransition: UIViewControllerTransitioningDelegate {
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
func animationController(forDismissed dismissed: UIViewController) -> (any UIViewControllerAnimatedTransitioning)? {
dismissing = true
return self
}
func animationController(forPresented presented: UIViewController,
presenting: UIViewController,
source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
source: UIViewController) -> (any UIViewControllerAnimatedTransitioning)? {
dismissing = false
return self
}
func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
func interactionControllerForDismissal(using animator: any UIViewControllerAnimatedTransitioning) -> (any UIViewControllerInteractiveTransitioning)? {
return interactive ? self : nil
}
func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
func interactionControllerForPresentation(using animator: any UIViewControllerAnimatedTransitioning) -> (any UIViewControllerInteractiveTransitioning)? {
return interactive ? self : nil
}
}
+6 -14
View File
@@ -1,13 +1,15 @@
import UIKit
import AVKit
import AVFoundation
import Imaginary
public class LightboxConfig {
/// Whether to show status bar while Lightbox is presented
public static var hideStatusBar = true
public static var imageBackgroundColor = UIColor.black
/// Provide a closure to handle selected video
@MainActor
public static var handleVideo: (_ from: UIViewController, _ videoURL: URL) -> Void = { from, videoURL in
let videoController = AVPlayerViewController()
videoController.player = AVPlayer(url: videoURL)
@@ -17,21 +19,11 @@ public class LightboxConfig {
}
}
/// How to load image onto UIImageView
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
switch result {
case .value(let image):
completion?(image)
case .error:
completion?(nil)
}
})
}
/// How to load image onto SDAnimatedImageView
public static var loadImage: ((UIImageView, URL, ((UIImage?) -> Void)?) -> Void)?
/// Indicator is used to show while image is being fetched
@MainActor
public static var makeLoadingIndicator: () -> UIView = {
return LoadingIndicator()
}
+45 -19
View File
@@ -1,20 +1,32 @@
import UIKit
public protocol LightboxControllerPageDelegate: class {
public protocol LightboxControllerPageDelegate: AnyObject {
@MainActor
func lightboxController(_ controller: LightboxController, didMoveToPage page: Int)
}
public protocol LightboxControllerDismissalDelegate: class {
public protocol LightboxControllerDismissalDelegate: AnyObject {
@MainActor
func lightboxControllerWillDismiss(_ controller: LightboxController)
}
public protocol LightboxControllerTouchDelegate: class {
public protocol LightboxControllerTouchDelegate: AnyObject {
@MainActor
func lightboxController(_ controller: LightboxController, didTouch image: LightboxImage, at index: Int)
}
public protocol LightboxControllerTapDelegate: AnyObject {
@MainActor
func lightboxController(_ controller: LightboxController, didTap image: LightboxImage, at index: Int)
@MainActor
func lightboxController(_ controller: LightboxController, didDoubleTap image: LightboxImage, at index: Int)
}
public protocol LightboxControllerDeleteDelegate: AnyObject {
@MainActor
func lightboxController(_ controller: LightboxController, willDeleteAt index: Int)
}
open class LightboxController: UIViewController {
// MARK: - Internal views
@@ -136,9 +148,11 @@ open class LightboxController: UIViewController {
}
}
open weak var pageDelegate: LightboxControllerPageDelegate?
open weak var dismissalDelegate: LightboxControllerDismissalDelegate?
open weak var imageTouchDelegate: LightboxControllerTouchDelegate?
open weak var pageDelegate: (any LightboxControllerPageDelegate)?
open weak var dismissalDelegate: (any LightboxControllerDismissalDelegate)?
open weak var imageTouchDelegate: (any LightboxControllerTouchDelegate)?
open weak var imageTapDelegate: (any LightboxControllerTapDelegate)?
open weak var imageDeleteDelegate: (any LightboxControllerDeleteDelegate)?
open internal(set) var presented = false
open fileprivate(set) var seen = false
@@ -166,9 +180,13 @@ open class LightboxController: UIViewController {
open override func viewDidLoad() {
super.viewDidLoad()
// 9 July 2020: @3lvis
// Lightbox hasn't been optimized to be used in presentation styles other than fullscreen.
modalPresentationStyle = .fullScreen
statusBarHidden = UIApplication.shared.isStatusBarHidden
view.backgroundColor = UIColor.black
view.backgroundColor = LightboxConfig.imageBackgroundColor
transitionManager.lightboxController = self
transitionManager.scrollView = scrollView
transitioningDelegate = transitionManager
@@ -181,14 +199,6 @@ open class LightboxController: UIViewController {
goTo(initialPage, animated: false)
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !presented {
presented = true
configureLayout(view.bounds.size)
}
}
open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
@@ -209,6 +219,11 @@ open class LightboxController: UIViewController {
width: view.bounds.width,
height: 100
)
if !presented {
presented = true
configureLayout(view.bounds.size)
}
}
open override var prefersStatusBarHidden: Bool {
@@ -217,7 +232,7 @@ open class LightboxController: UIViewController {
// MARK: - Rotation
override open func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
override open func viewWillTransition(to size: CGSize, with coordinator: any UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: { _ in
@@ -412,6 +427,14 @@ extension LightboxController: PageViewDelegate {
let visible = (headerView.alpha == 1.0)
toggleControls(pageView: pageView, visible: !visible)
}
func pageViewDidTap(_ pageView: PageView) {
imageTapDelegate?.lightboxController(self, didTap: images[currentPage], at: currentPage)
}
func pageViewDidDoubleTap(_ pageView: PageView) {
imageTapDelegate?.lightboxController(self, didDoubleTap: images[currentPage], at: currentPage)
}
}
// MARK: - HeaderViewDelegate
@@ -421,6 +444,8 @@ extension LightboxController: HeaderViewDelegate {
func headerView(_ headerView: HeaderView, didPressDeleteButton deleteButton: UIButton) {
deleteButton.isEnabled = false
imageDeleteDelegate?.lightboxController(self, willDeleteAt: currentPage)
guard numberOfPages != 1 else {
pageViews.removeAll()
self.headerView(headerView, didPressCloseButton: headerView.closeButton)
@@ -436,6 +461,7 @@ extension LightboxController: HeaderViewDelegate {
currentPage -= 1
}
self.initialImages.remove(at: prevIndex)
self.pageViews.remove(at: prevIndex).removeFromSuperview()
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) {
+8 -2
View File
@@ -1,5 +1,4 @@
import UIKit
import Imaginary
open class LightboxImage {
@@ -38,7 +37,14 @@ open class LightboxImage {
imageView.image = image
completion?(image)
} else if let imageURL = imageURL {
LightboxConfig.loadImage(imageView, imageURL, completion)
guard let loadImage = LightboxConfig.loadImage else {
print("Lightbox: To use `imageURL`, you must use `LightboxConfig.loadImage`.")
imageView.image = nil
completion?(nil)
return
}
loadImage(imageView, imageURL, completion)
} else if let imageClosure = imageClosure {
let img = imageClosure()
imageView.image = img
+3 -3
View File
@@ -1,7 +1,7 @@
import UIKit
public protocol FooterViewDelegate: class {
public protocol FooterViewDelegate: AnyObject {
@MainActor
func footerView(_ footerView: FooterView, didExpand expanded: Bool)
}
@@ -35,7 +35,7 @@ open class FooterView: UIView {
}()
let gradientColors = [UIColor(hex: "040404").withAlphaComponent(0.1), UIColor(hex: "040404")]
open weak var delegate: FooterViewDelegate?
open weak var delegate: (any FooterViewDelegate)?
// MARK: - Initializers
+4 -2
View File
@@ -1,7 +1,9 @@
import UIKit
protocol HeaderViewDelegate: class {
protocol HeaderViewDelegate: AnyObject {
@MainActor
func headerView(_ headerView: HeaderView, didPressDeleteButton deleteButton: UIButton)
@MainActor
func headerView(_ headerView: HeaderView, didPressCloseButton closeButton: UIButton)
}
@@ -60,7 +62,7 @@ open class HeaderView: UIView {
return button
}()
weak var delegate: HeaderViewDelegate?
weak var delegate: (any HeaderViewDelegate)?
// MARK: - Initializers
+3 -3
View File
@@ -1,7 +1,7 @@
import UIKit
public protocol InfoLabelDelegate: class {
public protocol InfoLabelDelegate: AnyObject {
@MainActor
func infoLabel(_ infoLabel: InfoLabel, didExpand expanded: Bool)
}
@@ -20,7 +20,7 @@ open class InfoLabel: UILabel {
return "... \(LightboxConfig.InfoLabel.ellipsisText)"
}
open weak var delegate: InfoLabelDelegate?
open weak var delegate: (any InfoLabelDelegate)?
fileprivate var shortText = ""
var fullText: String {
+25 -5
View File
@@ -1,12 +1,18 @@
import UIKit
protocol PageViewDelegate: class {
protocol PageViewDelegate: AnyObject {
@MainActor
func pageViewDidZoom(_ pageView: PageView)
@MainActor
func remoteImageDidLoad(_ image: UIImage?, imageView: UIImageView)
@MainActor
func pageView(_ pageView: PageView, didTouchPlayButton videoURL: URL)
@MainActor
func pageViewDidTouch(_ pageView: PageView)
}
@MainActor
func pageViewDidTap(_ pageView: PageView)
@MainActor
func pageViewDidDoubleTap(_ pageView: PageView)}
class PageView: UIScrollView {
@@ -22,8 +28,20 @@ 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: UIControl.State())
var buttonImage = AssetManager.image("lightbox_play")
// Note by Elvis Nuñez on Mon 22 Jun 08:06
// When using SPM you might find that assets are note included. This is a workaround to provide default assets
// under iOS 13 so using SPM can work without problems.
if #available(iOS 13.0, *) {
if buttonImage == nil {
buttonImage = UIImage(systemName: "play.circle.fill")
}
}
button.setBackgroundImage(buttonImage, for: UIControl.State())
button.addTarget(self, action: #selector(playButtonTouched(_:)), for: .touchUpInside)
button.tintColor = .white
button.layer.shadowOffset = CGSize(width: 1, height: 1)
button.layer.shadowColor = UIColor.gray.cgColor
@@ -37,7 +55,7 @@ class PageView: UIScrollView {
var image: LightboxImage
var contentFrame = CGRect.zero
weak var pageViewDelegate: PageViewDelegate?
weak var pageViewDelegate: (any PageViewDelegate)?
var hasZoomed: Bool {
return zoomScale != 1.0
@@ -134,10 +152,12 @@ class PageView: UIScrollView {
let rectToZoomTo = CGRect(x: x, y: y, width: width, height: height)
zoom(to: rectToZoomTo, animated: true)
pageViewDelegate?.pageViewDidDoubleTap(self)
}
@objc func viewTapped(_ recognizer: UITapGestureRecognizer) {
pageViewDelegate?.pageViewDidTouch(self)
pageViewDelegate?.pageViewDidTap(self)
}
// MARK: - Layout
+1 -1
View File
@@ -3,7 +3,7 @@ import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
lazy var controller: UIViewController = ViewController()
lazy var controller: UINavigationController = UINavigationController(rootViewController: ViewController())
var window: UIWindow?
+38 -24
View File
@@ -1,5 +1,6 @@
import UIKit
import Lightbox
import SDWebImage
class ViewController: UIViewController {
@@ -21,33 +22,46 @@ class ViewController: UIViewController {
view.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin, .flexibleBottomMargin]
view.backgroundColor = UIColor.white
view.addSubview(showButton)
title = "Lightbox"
LightboxConfig.preload = 2
LightboxConfig.loadImage = { imageView, url, completion in
imageView.sd_setImage(with: url) { image, _, _ , _ in
completion?(image)
}
}
}
// MARK: - Action methods
@objc func showLightbox() {
let images = [
LightboxImage(imageURL: URL(string: "https://cdn.arstechnica.net/2011/10/05/iphone4s_sample_apple-4e8c706-intro.jpg")!),
LightboxImage(
image: UIImage(named: "photo1")!,
text: "Photography is the science, art, application and practice of creating durable images by recording light or other electromagnetic radiation, either electronically by means of an image sensor, or chemically by means of a light-sensitive material such as photographic film"
),
LightboxImage(
image: UIImage(named: "photo2")!,
text: "Emoji 😍 (/ɪˈmoʊdʒi/; singular emoji, plural emoji or emojis;[4] from the Japanese 絵文字えもじ, pronounced [emodʑi]) are ideograms and smileys used in electronic messages and web pages. Emoji are used much like emoticons and exist in various genres, including facial expressions, common objects, places and types of weather 🌅☔️💦, and animals 🐶🐱",
videoURL: URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
),
LightboxImage(
image: UIImage(named: "photo3")!,
text: "A lightbox is a translucent surface illuminated from behind, used for situations where a shape laid upon the surface needs to be seen with high contrast."
)
]
let controller = LightboxController(images: images)
controller.modalPresentationStyle = .fullScreen
controller.dynamicBackground = true
present(controller, animated: true, completion: nil)
}
@objc func showLightbox() {
let images = [
LightboxImage(imageURL: URL(string: "https://media.giphy.com/media/Ku65904QQe4yez448B/giphy.gif")!),
LightboxImage(imageURL: URL(string: "https://media.giphy.com/media/lQDLwWUMPaAHvh8pAG/giphy.gif")!),
LightboxImage(imageURL: URL(string: "https://media.giphy.com/media/ontKwPWJxARsuKaKqJ/giphy.gif")!),
LightboxImage(
image: UIImage(named: "photo1")!,
text: "Photography is the science, art, application and practice of creating durable images by recording light or other electromagnetic radiation, either electronically by means of an image sensor, or chemically by means of a light-sensitive material such as photographic film"
),
LightboxImage(imageURL: URL(string: "https://via.placeholder.com/300.png/09f/fff")!),
LightboxImage(
image: UIImage(named: "photo2")!,
text: "Emoji 😍 (/ɪˈmoʊdʒi/; singular emoji, plural emoji or emojis;[4] from the Japanese 絵文字えもじ, pronounced [emodʑi]) are ideograms and smileys used in electronic messages and web pages. Emoji are used much like emoticons and exist in various genres, including facial expressions, common objects, places and types of weather 🌅☔️💦, and animals 🐶🐱",
videoURL: URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
),
LightboxImage(
image: UIImage(named: "photo3")!,
text: "A lightbox is a translucent surface illuminated from behind, used for situations where a shape laid upon the surface needs to be seen with high contrast."
),
LightboxImage(imageURL: URL(string: "https://c.tenor.com/kccsHXtdDn0AAAAC/alcohol-wine.gif")!)
]
let controller = LightboxController(images: images)
controller.dynamicBackground = true
present(controller, animated: true, completion: nil)
}
}