From d2e350c1d336fccbabd2cc06916b5dba60366598 Mon Sep 17 00:00:00 2001 From: suzuki_keishi Date: Fri, 12 Aug 2016 20:27:30 +0900 Subject: [PATCH] [refactor]update for swift3.0, new function. --- SKPhotoBrowser.xcodeproj/project.pbxproj | 10 +- SKPhotoBrowser/SKAnimator.swift | 12 +- SKPhotoBrowser/SKButtons.swift | 47 ++- SKPhotoBrowser/SKPhotoBrowser.swift | 302 ++++++------------ SKPhotoBrowser/SKToolbar.swift | 166 ++++++++++ SKPhotoBrowser/SKZoomingScrollView.swift | 8 +- .../FromCameraRollViewController.swift | 6 +- .../FromLocalViewController.swift | 3 + 8 files changed, 310 insertions(+), 244 deletions(-) create mode 100644 SKPhotoBrowser/SKToolbar.swift diff --git a/SKPhotoBrowser.xcodeproj/project.pbxproj b/SKPhotoBrowser.xcodeproj/project.pbxproj index 94a62b2..da02190 100644 --- a/SKPhotoBrowser.xcodeproj/project.pbxproj +++ b/SKPhotoBrowser.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ 8909B5491BC791510060A053 /* SKPhotoBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8909B5411BC791510060A053 /* SKPhotoBrowser.swift */; }; 8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8909B5421BC791510060A053 /* SKZoomingScrollView.swift */; }; 8909B54D1BC7916E0060A053 /* SKPhotoBrowser.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */; }; + 890A6F201D5D9E53003B01F0 /* SKToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 890A6F1F1D5D9E53003B01F0 /* SKToolbar.swift */; }; 8917B1B01D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8917B1AF1D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift */; }; 8917B1B21D5A1407000CE1C4 /* SKPhotoBrowserAnimatorDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8917B1B11D5A1407000CE1C4 /* SKPhotoBrowserAnimatorDelegate.swift */; }; 8917B1B41D5A14B0000CE1C4 /* SKButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */; }; @@ -58,6 +59,7 @@ 8909B5411BC791510060A053 /* SKPhotoBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowser.swift; sourceTree = ""; }; 8909B5421BC791510060A053 /* SKZoomingScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKZoomingScrollView.swift; sourceTree = ""; }; 8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SKPhotoBrowser.bundle; sourceTree = ""; }; + 890A6F1F1D5D9E53003B01F0 /* SKToolbar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKToolbar.swift; sourceTree = ""; }; 8917B1AF1D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowserDelegate.swift; sourceTree = ""; }; 8917B1B11D5A1407000CE1C4 /* SKPhotoBrowserAnimatorDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKPhotoBrowserAnimatorDelegate.swift; sourceTree = ""; }; 8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SKButtons.swift; sourceTree = ""; }; @@ -118,22 +120,23 @@ 8909B5321BC791280060A053 /* SKPhotoBrowser */ = { isa = PBXGroup; children = ( - 8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */, 89D0BA461D5994A8002A811B /* SKAnimator.swift */, + 8917B1B31D5A14B0000CE1C4 /* SKButtons.swift */, 26C97AD41D0EB6870039F6CB /* SKCache.swift */, 26C97AD81D0EB8BB0039F6CB /* SKCacheable.swift */, 8909B53B1BC791510060A053 /* SKCaptionView.swift */, 8909B53C1BC791510060A053 /* SKDetectingImageView.swift */, 8909B53D1BC791510060A053 /* SKDetectingView.swift */, 8909B53E1BC791510060A053 /* SKIndicatorView.swift */, - 8909B53F1BC791510060A053 /* SKPhoto.swift */, 8CA6C6511CBE76E80054D3C2 /* SKLocalPhoto.swift */, + 8909B53F1BC791510060A053 /* SKPhoto.swift */, 8909B5411BC791510060A053 /* SKPhotoBrowser.swift */, 8917B1B11D5A1407000CE1C4 /* SKPhotoBrowserAnimatorDelegate.swift */, - 8909B5421BC791510060A053 /* SKZoomingScrollView.swift */, + 890A6F1F1D5D9E53003B01F0 /* SKToolbar.swift */, 8909B5331BC791280060A053 /* SKPhotoBrowser.h */, 8917B1AF1D5A13DE000CE1C4 /* SKPhotoBrowserDelegate.swift */, 89D0BA481D59966B002A811B /* SKMesurement.swift */, + 8909B5421BC791510060A053 /* SKZoomingScrollView.swift */, 8909B5351BC791280060A053 /* Info.plist */, 210E53EB1C986D1C008DD5E3 /* extensions */, 8909B54C1BC7916E0060A053 /* SKPhotoBrowser.bundle */, @@ -278,6 +281,7 @@ buildActionMask = 2147483647; files = ( 26C97AD91D0EB8BB0039F6CB /* SKCacheable.swift in Sources */, + 890A6F201D5D9E53003B01F0 /* SKToolbar.swift in Sources */, 8917B1B21D5A1407000CE1C4 /* SKPhotoBrowserAnimatorDelegate.swift in Sources */, 8909B5441BC791510060A053 /* SKDetectingImageView.swift in Sources */, 8909B54A1BC791510060A053 /* SKZoomingScrollView.swift in Sources */, diff --git a/SKPhotoBrowser/SKAnimator.swift b/SKPhotoBrowser/SKAnimator.swift index 137526d..3234ddc 100644 --- a/SKPhotoBrowser/SKAnimator.swift +++ b/SKPhotoBrowser/SKAnimator.swift @@ -19,21 +19,19 @@ class SKAnimator: NSObject, SKPhotoBrowserAnimatorDelegate { var bounceAnimation: Bool = false var animationDuration: NSTimeInterval { - if bounceAnimation { + if SKPhotoBrowserOptions.bounceAnimation { return 0.5 } return 0.35 } var animationDamping: CGFloat { - if bounceAnimation { + if SKPhotoBrowserOptions.bounceAnimation { return 0.8 } return 1 } func willPresent(browser: SKPhotoBrowser) { - bounceAnimation = browser.bounceAnimation - guard let appWindow = UIApplication.sharedApplication().delegate?.window else { return } @@ -70,7 +68,7 @@ class SKAnimator: NSObject, SKPhotoBrowserAnimatorDelegate { image = browser.photoAtIndex(browser.currentPageIndex).underlyingImage else { senderViewForAnimation?.hidden = false - browser.dismissPhotoBrowser() + browser.dismissPhotoBrowser(animated: false) return } @@ -152,7 +150,7 @@ private extension SKAnimator { }, completion: { (Bool) -> Void in browser.view.hidden = false - browser.pagingScrollView.alpha = 1.0 + browser.view.alpha = 1.0 browser.backgroundView.hidden = true self.resizableImageView?.alpha = 0.0 @@ -172,7 +170,7 @@ private extension SKAnimator { self.resizableImageView?.layer.frame = self.senderViewOriginalFrame }, completion: { (Bool) -> () in - browser.dismissPhotoBrowser() { + browser.dismissPhotoBrowser(animated: true) { self.resizableImageView?.removeFromSuperview() } }) diff --git a/SKPhotoBrowser/SKButtons.swift b/SKPhotoBrowser/SKButtons.swift index a9b9c3c..cb9cdea 100644 --- a/SKPhotoBrowser/SKButtons.swift +++ b/SKPhotoBrowser/SKButtons.swift @@ -27,28 +27,18 @@ class SKButtons { init(browser: SKPhotoBrowser) { self.browser = browser - setCustomSetting() setSettingCloseButton() setSettingDeleteButton() } - func setup() { } - - private func setCustomSetting() { - // if displayCustomCloseButton == true { - // displayCloseButton = false - // } - // if displayCustomDeleteButton == true { - // displayDeleteButton = false - // } - } + func setup() {} private func setSettingCloseButton() { guard let browser = browser else { return } closeButton = SKCloseButton(frame: browser.view.frame) - closeButton.addTarget(self, action: #selector(browser.closeButtonPressed(_:)), forControlEvents: .TouchUpInside) - closeButton.hidden = !browser.displayCloseButton + closeButton.addTarget(browser, action: #selector(browser.closeButtonPressed(_:)), forControlEvents: .TouchUpInside) + closeButton.hidden = !SKPhotoBrowserOptions.displayCloseButton browser.view.addSubview(closeButton) // If another developer has not set their values @@ -64,8 +54,8 @@ class SKButtons { guard let browser = browser else { return } deleteButton = SKDeleteButton(frame: browser.view.frame) - deleteButton.addTarget(self, action: #selector(browser.deleteButtonPressed(_:)), forControlEvents: .TouchUpInside) - deleteButton.hidden = !browser.displayDeleteButton + deleteButton.addTarget(browser, action: #selector(browser.deleteButtonPressed(_:)), forControlEvents: .TouchUpInside) + deleteButton.hidden = !SKPhotoBrowserOptions.displayDeleteButton browser.view.addSubview(deleteButton) // If another developer has not set their values @@ -76,7 +66,6 @@ class SKButtons { deleteButton.imageEdgeInsets = customCloseButtonEdgeInsets } } - } class SKButton: UIButton { @@ -89,10 +78,8 @@ class SKButton: UIButton { var size: CGSize = CGSize(width: 44, height: 44) var margin: CGFloat = 5 - var buttonTopOffset: CGFloat { - return UIApplication.sharedApplication().statusBarHidden ? 25 : 5 - } - + var buttonTopOffset: CGFloat { return 5 } + func setup(imageName: String) { backgroundColor = .clearColor() imageEdgeInsets = insets @@ -103,6 +90,8 @@ class SKButton: UIButton { inBundle: bundle, compatibleWithTraitCollection: nil) ?? UIImage() setImage(image, forState: .Normal) } + + func updateFrame() {} } class SKCloseButton: SKButton { @@ -114,10 +103,12 @@ class SKCloseButton: SKButton { override init(frame: CGRect) { super.init(frame: frame) setup(imageName) - showFrame = CGRect(x: margin, y: buttonTopOffset, width: size.width, height: size.height) hideFrame = CGRect(x: margin, y: -20, width: size.width, height: size.height) } + + override func updateFrame() { + } } class SKDeleteButton: SKButton { @@ -129,10 +120,16 @@ class SKDeleteButton: SKButton { override init(frame: CGRect) { super.init(frame: frame) setup(imageName) - - showFrame = CGRect(x: frame.width - size.width, y: buttonTopOffset, + showFrame = CGRect(x: SKMesurement.screenWidth - size.width, y: buttonTopOffset, width: size.width, height: size.height) - hideFrame = CGRect(x: frame.width - size.width, y: -20, + hideFrame = CGRect(x: SKMesurement.screenWidth - size.width, y: -20, width: size.width, height: size.height) } -} \ No newline at end of file + + override func updateFrame() { + showFrame = CGRect(x: SKMesurement.screenWidth - size.width, y: buttonTopOffset, + width: size.width, height: size.height) + hideFrame = CGRect(x: SKMesurement.screenWidth - size.width, y: -20, + width: size.width, height: size.height) + } +} diff --git a/SKPhotoBrowser/SKPhotoBrowser.swift b/SKPhotoBrowser/SKPhotoBrowser.swift index b0b27b5..3538f4a 100644 --- a/SKPhotoBrowser/SKPhotoBrowser.swift +++ b/SKPhotoBrowser/SKPhotoBrowser.swift @@ -10,72 +10,50 @@ import UIKit public let SKPHOTO_LOADING_DID_END_NOTIFICATION = "photoLoadingDidEndNotification" -// MARK: - SKPhotoBrowser -public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { +public struct SKPhotoBrowserOptions { + public static var displayAction: Bool = true + public static var shareExtraCaption: String? = nil + public static var actionButtonTitles: [String]? - final let pageIndexTagOffset: Int = 1000 - // animation property - var animationDuration: NSTimeInterval { - if bounceAnimation { - return 0.5 - } - return 0.35 - } - var animationDamping: CGFloat { - if bounceAnimation { - return 0.8 - } - return 1 - } + public static var displayToolbar: Bool = true + public static var displayCounterLabel: Bool = true + public static var displayBackAndForwardButton: Bool = true + public static var disableVerticalSwipe: Bool = false + + public static var displayCloseButton = true + public static var displayDeleteButton = false + + public static var bounceAnimation = false + public static var enableZoomBlackArea = true + public static var enableSingleTapDismiss = false +} + +// MARK: - SKPhotoBrowser +public class SKPhotoBrowser: UIViewController { + + let pageIndexTagOffset: Int = 1000 lazy var buttons: SKButtons = SKButtons(browser: self) - - // custom abilities - public var displayAction: Bool = true - public var shareExtraCaption: String? = nil - public var actionButtonTitles: [String]? - public var displayToolbar: Bool = true - public var displayCounterLabel: Bool = true - public var displayBackAndForwardButton: Bool = true - public var disableVerticalSwipe: Bool = false - public var displayDeleteButton = false - public var displayCloseButton = true // default is true - /// If it is true displayCloseButton will be false - public var displayCustomCloseButton = false - /// If it is true displayDeleteButton will be false - public var displayCustomDeleteButton = false - public var bounceAnimation = false - public var enableZoomBlackArea = true - public var enableSingleTapDismiss = false + lazy var toolbar: SKToolbar = SKToolbar(frame: self.frameForToolbarAtOrientation(), browser: self) // actions private var activityViewController: UIActivityViewController! + private var panGesture: UIPanGestureRecognizer! // tool for controls private var applicationWindow: UIWindow! + private var pagingScrollView: UIScrollView! var backgroundView: UIView! - private var toolBar: UIToolbar! - private var toolCounterLabel: UILabel! - private var toolCounterButton: UIBarButtonItem! - private var toolPreviousButton: UIBarButtonItem! - private var toolActionButton: UIBarButtonItem! - private var toolNextButton: UIBarButtonItem! - var pagingScrollView: UIScrollView! - private var panGesture: UIPanGestureRecognizer! - // MARK: close button + private var closeButton: SKCloseButton { return buttons.closeButton } private var deleteButton: SKDeleteButton { return buttons.deleteButton } - public var customCloseButtonImage: UIImage! - public var customCloseButtonEdgeInsets: UIEdgeInsets! - public var customDeleteButtonImage: UIImage! - public var customDeleteButtonEdgeInsets: UIEdgeInsets! // photo's paging - private var visiblePages = [SKZoomingScrollView]()//: Set = Set() + private var visiblePages = [SKZoomingScrollView]() private var recycledPages = [SKZoomingScrollView]() var initialPageIndex: Int = 0 @@ -87,11 +65,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { private var isViewActive: Bool = false private var isPerformingLayout: Bool = false - private var buttonTopOffset: CGFloat { - return 25 - } - - // scroll property + // pangesture property private var firstX: CGFloat = 0.0 private var firstY: CGFloat = 0.0 @@ -154,7 +128,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } applicationWindow = window -// modalPresentationCapturesStatusBarAppearance = true + modalPresentationCapturesStatusBarAppearance = true modalPresentationStyle = .Custom modalTransitionStyle = .CrossDissolve @@ -165,87 +139,11 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { override public func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .blackColor() - view.clipsToBounds = true - view.opaque = false - - - backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: SKMesurement.screenWidth, height: SKMesurement.screenHeight)) - backgroundView.backgroundColor = .blackColor() - backgroundView.alpha = 0.0 - applicationWindow.addSubview(backgroundView) - - // setup paging - let pagingScrollViewFrame = frameForPagingScrollView() - pagingScrollView = UIScrollView(frame: pagingScrollViewFrame) - pagingScrollView.pagingEnabled = true - pagingScrollView.delegate = self - pagingScrollView.showsHorizontalScrollIndicator = true - pagingScrollView.showsVerticalScrollIndicator = true - pagingScrollView.contentSize = contentSizeForPagingScrollView() - view.addSubview(pagingScrollView) - - // toolbar - toolBar = UIToolbar(frame: frameForToolbarAtOrientation()) - toolBar.backgroundColor = .clearColor() - toolBar.clipsToBounds = true - toolBar.translucent = true - toolBar.setBackgroundImage(UIImage(), forToolbarPosition: .Any, barMetrics: .Default) - view.addSubview(toolBar) - - if !displayToolbar { - toolBar.hidden = true - } - - // arrows:back - let previousBtn = UIButton(type: .Custom) - let previousImage = UIImage(named: "SKPhotoBrowser.bundle/images/btn_common_back_wh", inBundle: bundle, compatibleWithTraitCollection: nil) ?? UIImage() - previousBtn.frame = CGRect(x: 0, y: 0, width: 44, height: 44) - previousBtn.imageEdgeInsets = UIEdgeInsetsMake(13.25, 17.25, 13.25, 17.25) - previousBtn.setImage(previousImage, forState: .Normal) - previousBtn.addTarget(self, action: #selector(self.gotoPreviousPage), forControlEvents: .TouchUpInside) - previousBtn.contentMode = .Center - toolPreviousButton = UIBarButtonItem(customView: previousBtn) - - // arrows:next - let nextBtn = UIButton(type: .Custom) - let nextImage = UIImage(named: "SKPhotoBrowser.bundle/images/btn_common_forward_wh", inBundle: bundle, compatibleWithTraitCollection: nil) ?? UIImage() - nextBtn.frame = CGRect(x: 0, y: 0, width: 44, height: 44) - nextBtn.imageEdgeInsets = UIEdgeInsetsMake(13.25, 17.25, 13.25, 17.25) - nextBtn.setImage(nextImage, forState: .Normal) - nextBtn.addTarget(self, action: #selector(self.gotoNextPage), forControlEvents: .TouchUpInside) - nextBtn.contentMode = .Center - toolNextButton = UIBarButtonItem(customView: nextBtn) - - toolCounterLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 95, height: 40)) - toolCounterLabel.textAlignment = .Center - toolCounterLabel.backgroundColor = .clearColor() - toolCounterLabel.font = UIFont(name: "Helvetica", size: 16.0) - toolCounterLabel.textColor = .whiteColor() - toolCounterLabel.shadowColor = .darkTextColor() - toolCounterLabel.shadowOffset = CGSize(width: 0.0, height: 1.0) - - toolCounterButton = UIBarButtonItem(customView: toolCounterLabel) - - // starting setting -// setCustomSetting() -// setSettingCloseButton() -// setSettingDeleteButton() + setupAppearance() + toolbar.setup() buttons.setup() - // action button - toolActionButton = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: #selector(SKPhotoBrowser.actionButtonPressed)) - toolActionButton.tintColor = .whiteColor() - - // gesture - panGesture = UIPanGestureRecognizer(target: self, action: #selector(SKPhotoBrowser.panGestureRecognized(_:))) - panGesture.minimumNumberOfTouches = 1 - panGesture.maximumNumberOfTouches = 1 - - - // transition (this must be last call of view did load.) -// performPresentAnimation() animator.willPresent(self) } @@ -266,8 +164,8 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { pagingScrollView.frame = frameForPagingScrollView() pagingScrollView.contentSize = contentSizeForPagingScrollView() - // resize frames of buttons after the device rotation - frameForButton() + closeButton.updateFrame() + deleteButton.updateFrame() // this algorithm resizes the current image after device rotation if visiblePages.count > 0 { @@ -285,7 +183,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { // where did start didStartViewingPageAtIndex(currentPageIndex) - toolBar.frame = frameForToolbarAtOrientation() + toolbar.frame = frameForToolbarAtOrientation() isPerformingLayout = false } @@ -350,29 +248,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { public func performLayout() { isPerformingLayout = true - // for tool bar - let flexSpace = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: self, action: nil) - var items = [UIBarButtonItem]() - items.append(flexSpace) - if numberOfPhotos > 1 && displayBackAndForwardButton { - items.append(toolPreviousButton) - } - if displayCounterLabel { - items.append(flexSpace) - items.append(toolCounterButton) - items.append(flexSpace) - } else { - items.append(flexSpace) - } - if numberOfPhotos > 1 && displayBackAndForwardButton { - items.append(toolNextButton) - } - items.append(flexSpace) - if displayAction { - items.append(toolActionButton) - } - toolBar.setItems(items, animated: false) - updateToolbar() + toolbar.updateToolbar(currentPageIndex) // reset local cache visiblePages.forEach({$0.removeFromSuperview()}) @@ -389,17 +265,17 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { isPerformingLayout = false // add pangesture if need - if !disableVerticalSwipe { + if !SKPhotoBrowserOptions.disableVerticalSwipe { view.addGestureRecognizer(panGesture) } } func showButtons() { - if displayCloseButton { + if SKPhotoBrowserOptions.displayCloseButton { closeButton.alpha = 1 closeButton.frame = closeButton.showFrame } - if displayDeleteButton { + if SKPhotoBrowserOptions.displayDeleteButton { deleteButton.alpha = 1 deleteButton.frame = deleteButton.showFrame } @@ -464,10 +340,6 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { return CGSize(width: bounds.size.width * CGFloat(numberOfPhotos), height: bounds.size.height) } - /// This function changes buttons's frame after the rotation of the device - private func frameForButton() { - } - // MARK: - delete function @objc func deleteButtonPressed(sender: UIButton) { delegate?.removePhoto?(self, index: currentPageIndex, reload: { () -> Void in @@ -475,6 +347,32 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { }) } + private func setupAppearance() { + view.backgroundColor = .blackColor() + view.clipsToBounds = true + view.opaque = false + + backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: SKMesurement.screenWidth, height: SKMesurement.screenHeight)) + backgroundView.backgroundColor = .blackColor() + backgroundView.alpha = 0.0 + applicationWindow.addSubview(backgroundView) + + // setup paging + let pagingScrollViewFrame = frameForPagingScrollView() + pagingScrollView = UIScrollView(frame: pagingScrollViewFrame) + pagingScrollView.pagingEnabled = true + pagingScrollView.delegate = self + pagingScrollView.showsHorizontalScrollIndicator = true + pagingScrollView.showsVerticalScrollIndicator = true + pagingScrollView.contentSize = contentSizeForPagingScrollView() + view.addSubview(pagingScrollView) + + // gesture + panGesture = UIPanGestureRecognizer(target: self, action: #selector(SKPhotoBrowser.panGestureRecognized(_:))) + panGesture.minimumNumberOfTouches = 1 + panGesture.maximumNumberOfTouches = 1 + } + private func deleteImage() { if photos.count > 1 { // index equals 0 because when we slide between photos delete button is hidden and user cannot to touch on delete button. And visible pages number equals 0 @@ -483,25 +381,14 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { if currentPageIndex != 0 { gotoPreviousPage() } - updateToolbar() + toolbar.updateToolbar(currentPageIndex) + } else if photos.count == 1 { - dismissPhotoBrowser() + dismissPhotoBrowser(animated: false) } reloadData() } - // MARK: - Toolbar - public func updateToolbar() { - if numberOfPhotos > 1 { - toolCounterLabel.text = "\(currentPageIndex + 1) / \(numberOfPhotos)" - } else { - toolCounterLabel.text = nil - } - - toolPreviousButton.enabled = (currentPageIndex > 0) - toolNextButton.enabled = (currentPageIndex < numberOfPhotos - 1) - } - // MARK: - panGestureRecognized public func panGestureRecognized(sender: UIPanGestureRecognizer) { backgroundView.hidden = true @@ -541,7 +428,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { isDraggingPhoto = false setNeedsStatusBarAppearanceUpdate() - let velocityY: CGFloat = CGFloat(self.animationDuration) * sender.velocityInView(self.view).y + let velocityY: CGFloat = CGFloat(0.35) * sender.velocityInView(self.view).y let finalX: CGFloat = firstX let finalY: CGFloat = viewHalfHeight @@ -557,14 +444,22 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } } - public func dismissPhotoBrowser(completion: (Void -> Void)? = nil) { - modalTransitionStyle = .CrossDissolve + public func dismissPhotoBrowser(animated animated: Bool, completion: (Void -> Void)? = nil) { prepareForClosePhotoBrowser() - dismissViewControllerAnimated(true) { - completion?() - self.delegate?.didDismissAtPageIndex?(self.currentPageIndex) + if animated { + dismissViewControllerAnimated(false) { + completion?() + self.delegate?.didDismissAtPageIndex?(self.currentPageIndex) + } + } else { + modalTransitionStyle = .CrossDissolve + dismissViewControllerAnimated(true) { + completion?() + self.delegate?.didDismissAtPageIndex?(self.currentPageIndex) + } } + } public func determineAndClose() { @@ -573,7 +468,6 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } - //MARK: - image func getImageFromView(sender: UIView) -> UIImage { UIGraphicsBeginImageContextWithOptions(sender.frame.size, true, 0.0) sender.layer.renderInContext(UIGraphicsGetCurrentContext()!) @@ -608,7 +502,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { isEndAnimationByToolBar = false let pageFrame = frameForPageAtIndex(index) pagingScrollView.setContentOffset(CGPoint(x: pageFrame.origin.x - 10, y: 0), animated: true) - updateToolbar() + toolbar.updateToolbar(currentPageIndex) } hideControlsAfterDelay() } @@ -758,16 +652,16 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } } - UIView.animateWithDuration(animationDuration, + UIView.animateWithDuration(0.35, animations: { () -> Void in let alpha: CGFloat = hidden ? 0.0 : 1.0 - self.toolBar.alpha = alpha - self.toolBar.frame = hidden ? self.frameForToolbarHideAtOrientation() : self.frameForToolbarAtOrientation() - if self.displayCloseButton { + self.toolbar.alpha = alpha + self.toolbar.frame = hidden ? self.frameForToolbarHideAtOrientation() : self.frameForToolbarAtOrientation() + if SKPhotoBrowserOptions.displayCloseButton { self.closeButton.alpha = alpha self.closeButton.frame = hidden ? self.closeButton.hideFrame : self.closeButton.showFrame } - if self.displayDeleteButton { + if SKPhotoBrowserOptions.displayDeleteButton { self.deleteButton.alpha = alpha self.deleteButton.frame = hidden ? self.deleteButton.hideFrame : self.deleteButton.showFrame } @@ -785,7 +679,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } public func areControlsHidden() -> Bool { - return toolBar.alpha == 0.0 + return toolbar.alpha == 0.0 } // MARK: - Button @@ -803,7 +697,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { return } - if let titles = actionButtonTitles { + if let titles = SKPhotoBrowserOptions.actionButtonTitles { let actionSheetController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet) actionSheetController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action) -> Void in })) @@ -820,7 +714,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { if let popoverController = actionSheetController.popoverPresentationController { popoverController.sourceView = self.view - popoverController.barButtonItem = toolActionButton + popoverController.barButtonItem = toolbar.toolActionButton } presentViewController(actionSheetController, animated: true, completion: { () -> Void in @@ -833,7 +727,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { var activityItems: [AnyObject] = [underlyingImage] if photo.caption != nil { - if let shareExtraCaption = shareExtraCaption { + if let shareExtraCaption = SKPhotoBrowserOptions.shareExtraCaption { activityItems.append(photo.caption + shareExtraCaption) } else { activityItems.append(photo.caption) @@ -850,13 +744,18 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } else { activityViewController.modalPresentationStyle = .Popover let popover: UIPopoverPresentationController! = activityViewController.popoverPresentationController - popover.barButtonItem = toolActionButton + popover.barButtonItem = toolbar.toolActionButton presentViewController(activityViewController, animated: true, completion: nil) } } } - // MARK: - UIScrollView Delegate + +} + +// MARK: - UIScrollView Delegate + +extension SKPhotoBrowser: UIScrollViewDelegate { public func scrollViewDidScroll(scrollView: UIScrollView) { guard isViewActive else { return @@ -882,7 +781,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { currentPageIndex = index if currentPageIndex != previousCurrentPage { didStartViewingPageAtIndex(currentPageIndex) - updateToolbar() + toolbar.updateToolbar(currentPageIndex) } } @@ -892,7 +791,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { public func scrollViewDidEndDecelerating(scrollView: UIScrollView) { hideControlsAfterDelay() - + let currentIndex = self.pagingScrollView.contentOffset.x / self.pagingScrollView.frame.size.width self.delegate?.didScrollToIndex?(Int(currentIndex)) } @@ -900,5 +799,4 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { public func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) { isEndAnimationByToolBar = true } - -} +} \ No newline at end of file diff --git a/SKPhotoBrowser/SKToolbar.swift b/SKPhotoBrowser/SKToolbar.swift new file mode 100644 index 0000000..decd30f --- /dev/null +++ b/SKPhotoBrowser/SKToolbar.swift @@ -0,0 +1,166 @@ +// +// SKToolbar.swift +// SKPhotoBrowser +// +// Created by 鈴木 啓司 on 2016/08/12. +// Copyright © 2016年 suzuki_keishi. All rights reserved. +// + +import Foundation + +// helpers which often used +private let bundle = NSBundle(forClass: SKPhotoBrowser.self) + +class SKToolbar: UIToolbar { + var toolCounterLabel: UILabel! + var toolCounterButton: UIBarButtonItem! + var toolPreviousButton: UIBarButtonItem! + var toolNextButton: UIBarButtonItem! + var toolActionButton: UIBarButtonItem! + + private weak var browser: SKPhotoBrowser? + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override init(frame: CGRect) { + super.init(frame: frame) + } + + convenience init(frame: CGRect, browser: SKPhotoBrowser) { + self.init(frame: frame) + self.browser = browser + + setupToolbar() + setupPreviousButton() + setupNextButton() + setupCounterLabel() + setupActionButton() + } + + func setup() { + guard let browser = browser else { return } + + let flexSpace = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: self, action: nil) + var items = [UIBarButtonItem]() + items.append(flexSpace) + if browser.numberOfPhotos > 1 && SKPhotoBrowserOptions.displayBackAndForwardButton { + items.append(toolPreviousButton) + } + if SKPhotoBrowserOptions.displayCounterLabel { + items.append(flexSpace) + items.append(toolCounterButton) + items.append(flexSpace) + } else { + items.append(flexSpace) + } + if browser.numberOfPhotos > 1 && SKPhotoBrowserOptions.displayBackAndForwardButton { + items.append(toolNextButton) + } + items.append(flexSpace) + if SKPhotoBrowserOptions.displayAction { + items.append(toolActionButton) + } + setItems(items, animated: false) + } + + func updateToolbar(currentPageIndex: Int) { + guard let browser = browser else { return } + + if browser.numberOfPhotos > 1 { + toolCounterLabel.text = "\(currentPageIndex + 1) / \(browser.numberOfPhotos)" + } else { + toolCounterLabel.text = nil + } + + toolPreviousButton.enabled = (currentPageIndex > 0) + toolNextButton.enabled = (currentPageIndex < browser.numberOfPhotos - 1) + } +} + +private extension SKToolbar { + func setupToolbar() { + guard let browser = browser else { return } + + backgroundColor = .clearColor() + clipsToBounds = true + translucent = true + setBackgroundImage(UIImage(), forToolbarPosition: .Any, barMetrics: .Default) + browser.view.addSubview(self) + + // toolbar + if !SKPhotoBrowserOptions.displayToolbar { + hidden = true + } + } + + func setupPreviousButton() { + let previousBtn = SKPreviousButton(frame: frame) + previousBtn.addTarget(browser, action: #selector(SKPhotoBrowser.gotoPreviousPage), forControlEvents: .TouchUpInside) + toolPreviousButton = UIBarButtonItem(customView: previousBtn) + } + + func setupNextButton() { + let nextBtn = SKNextButton(frame: frame) + nextBtn.addTarget(browser, action: #selector(SKPhotoBrowser.gotoNextPage), forControlEvents: .TouchUpInside) + toolNextButton = UIBarButtonItem(customView: nextBtn) + } + + func setupCounterLabel() { + toolCounterLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 95, height: 40)) + toolCounterLabel.textAlignment = .Center + toolCounterLabel.backgroundColor = .clearColor() + toolCounterLabel.font = UIFont(name: "Helvetica", size: 16.0) + toolCounterLabel.textColor = .whiteColor() + toolCounterLabel.shadowColor = .darkTextColor() + toolCounterLabel.shadowOffset = CGSize(width: 0.0, height: 1.0) + toolCounterButton = UIBarButtonItem(customView: toolCounterLabel) + } + + func setupActionButton() { + toolActionButton = UIBarButtonItem(barButtonSystemItem: .Action, target: browser, action: #selector(SKPhotoBrowser.actionButtonPressed)) + toolActionButton.tintColor = .whiteColor() + } +} + + +class SKToolbarButton: UIButton { + let insets: UIEdgeInsets = UIEdgeInsetsMake(13.25, 17.25, 13.25, 17.25) + + func setup(imageName: String) { + backgroundColor = .clearColor() + imageEdgeInsets = insets + translatesAutoresizingMaskIntoConstraints = true + autoresizingMask = [.FlexibleBottomMargin, .FlexibleLeftMargin, .FlexibleRightMargin, .FlexibleTopMargin] + contentMode = .Center + + let image = UIImage(named: "SKPhotoBrowser.bundle/images/\(imageName)", + inBundle: bundle, compatibleWithTraitCollection: nil) ?? UIImage() + setImage(image, forState: .Normal) + } +} + +class SKPreviousButton: SKToolbarButton { + let imageName = "btn_common_back_wh" + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override init(frame: CGRect) { + super.init(frame: CGRect(x: 0, y: 0, width: 44, height: 44)) + setup(imageName) + } +} + +class SKNextButton: SKToolbarButton { + let imageName = "btn_common_forward_wh" + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override init(frame: CGRect) { + super.init(frame: CGRect(x: 0, y: 0, width: 44, height: 44)) + setup(imageName) + } +} \ No newline at end of file diff --git a/SKPhotoBrowser/SKZoomingScrollView.swift b/SKPhotoBrowser/SKZoomingScrollView.swift index 8bf7675..89ccb98 100644 --- a/SKPhotoBrowser/SKZoomingScrollView.swift +++ b/SKPhotoBrowser/SKZoomingScrollView.swift @@ -274,11 +274,11 @@ public class SKZoomingScrollView: UIScrollView, UIScrollViewDelegate, SKDetectin guard let browser = photoBrowser else { return } - guard browser.enableZoomBlackArea == true else { + guard SKPhotoBrowserOptions.enableZoomBlackArea == true else { return } - if browser.areControlsHidden() == false && browser.enableSingleTapDismiss == true { + if browser.areControlsHidden() == false && SKPhotoBrowserOptions.enableSingleTapDismiss == true { browser.determineAndClose() } else { browser.toggleControls() @@ -286,7 +286,7 @@ public class SKZoomingScrollView: UIScrollView, UIScrollViewDelegate, SKDetectin } func handleDoubleTap(view: UIView, touch: UITouch) { - if photoBrowser?.enableZoomBlackArea == true { + if SKPhotoBrowserOptions.enableZoomBlackArea == true { let needPoint = getViewFramePercent(view, touch: touch) handleDoubleTap(needPoint) } @@ -318,7 +318,7 @@ public class SKZoomingScrollView: UIScrollView, UIScrollViewDelegate, SKDetectin guard let browser = photoBrowser else { return } - if browser.enableSingleTapDismiss { + if SKPhotoBrowserOptions.enableSingleTapDismiss { browser.determineAndClose() } else { browser.toggleControls() diff --git a/SKPhotoBrowserExample/SKPhotoBrowserExample/FromCameraRollViewController.swift b/SKPhotoBrowserExample/SKPhotoBrowserExample/FromCameraRollViewController.swift index cf4d86c..51e9cd5 100644 --- a/SKPhotoBrowserExample/SKPhotoBrowserExample/FromCameraRollViewController.swift +++ b/SKPhotoBrowserExample/SKPhotoBrowserExample/FromCameraRollViewController.swift @@ -107,9 +107,9 @@ class FromCameraRollViewController: UIViewController, SKPhotoBrowserDelegate, UI browser.initializePageIndex(indexPath.row) browser.delegate = self - browser.bounceAnimation = true - browser.displayDeleteButton = true - browser.displayAction = false +// browser.bounceAnimation = true +// browser.displayDeleteButton = true +// browser.displayAction = false self.presentViewController(browser, animated: true, completion: {}) } diff --git a/SKPhotoBrowserExample/SKPhotoBrowserExample/FromLocalViewController.swift b/SKPhotoBrowserExample/SKPhotoBrowserExample/FromLocalViewController.swift index 3c7870f..76c5510 100644 --- a/SKPhotoBrowserExample/SKPhotoBrowserExample/FromLocalViewController.swift +++ b/SKPhotoBrowserExample/SKPhotoBrowserExample/FromLocalViewController.swift @@ -61,6 +61,9 @@ extension FromLocalViewController { guard let originImage = cell.exampleImageView.image else { return } + +// SKPhotoBrowserOptions.displayDeleteButton = true + let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell) // let browser = SKPhotoBrowser(photos: images) browser.initializePageIndex(indexPath.row)