From 30ef41ee61e12f76b96b583ebb691d648c19fc08 Mon Sep 17 00:00:00 2001 From: Kevin Rummler Date: Wed, 9 Mar 2016 17:02:51 +0100 Subject: [PATCH] Several tweaks and impovements Add support for cornerRadius transition Option to bounce transition Animate properly from zoomed/panned state --- SKPhotoBrowser/SKPhotoBrowser.swift | 92 ++++++++++++++----- SKPhotoBrowser/SKZoomingScrollView.swift | 2 +- .../project.pbxproj | 24 ++--- .../Base.lproj/Main.storyboard | 6 +- .../ViewController.swift | 3 + 5 files changed, 87 insertions(+), 40 deletions(-) diff --git a/SKPhotoBrowser/SKPhotoBrowser.swift b/SKPhotoBrowser/SKPhotoBrowser.swift index 8ffc9a9..89648ca 100644 --- a/SKPhotoBrowser/SKPhotoBrowser.swift +++ b/SKPhotoBrowser/SKPhotoBrowser.swift @@ -24,7 +24,18 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { final let pageIndexTagOffset: Int = 1000 // animation property - final let animationDuration: Double = 0.35 + var animationDuration: NSTimeInterval { + if bounceAnimation { + return 0.5 + } + return 0.35 + } + var animationDamping: CGFloat { + if bounceAnimation { + return 0.8 + } + return 1 + } // device property final let screenBound = UIScreen.mainScreen().bounds @@ -44,6 +55,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { public var displayCloseButton = true // default is true public var displayCustomCloseButton = false // if it is true displayCloseButton will be false public var displayCustomDeleteButton = false // if it is true displayDeleteButton will be false + public var bounceAnimation = false // actions private var activityViewController: UIActivityViewController! @@ -242,7 +254,6 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { setSettingCustomCloseButton() setSettingCustomDeleteButton() - // action button toolActionButton = UIBarButtonItem(barButtonSystemItem: .Action, target: self, action: "actionButtonPressed") toolActionButton.tintColor = .whiteColor() @@ -252,7 +263,6 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { panGesture.minimumNumberOfTouches = 1 panGesture.maximumNumberOfTouches = 1 - // transition (this must be last call of view did load.) performPresentAnimation() } @@ -649,10 +659,9 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { finalY = -(viewHalfHeight) } - let animationDuration = 0.35 UIView.beginAnimations(nil, context: nil) UIView.setAnimationDuration(animationDuration) - UIView.setAnimationCurve(UIViewAnimationCurve.EaseIn) + UIView.setAnimationCurve(.EaseIn) scrollView.center = CGPoint(x: finalX, y: finalY) UIView.commitAnimations() @@ -663,7 +672,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { isDraggingPhoto = false setNeedsStatusBarAppearanceUpdate() - let velocityY: CGFloat = 0.35 * sender.velocityInView(self.view).y + let velocityY: CGFloat = CGFloat(self.animationDuration) * sender.velocityInView(self.view).y let finalX: CGFloat = firstX let finalY: CGFloat = viewHalfHeight @@ -684,19 +693,20 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { view.alpha = 0.0 pagingScrollView.alpha = 0.0 + let fadeView = UIView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)) + fadeView.backgroundColor = .blackColor() + fadeView.alpha = 0.0 + applicationWindow.addSubview(fadeView) + if let sender = senderViewForAnimation { senderViewOriginalFrame = (sender.superview?.convertRect(sender.frame, toView:nil))! - let fadeView = UIView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)) - fadeView.backgroundColor = UIColor.clearColor() - applicationWindow.addSubview(fadeView) - let imageFromView = senderOriginImage != nil ? senderOriginImage : getImageFromView(sender) resizableImageView = UIImageView(image: imageFromView) resizableImageView.frame = senderViewOriginalFrame resizableImageView.clipsToBounds = true - resizableImageView.contentMode = .ScaleToFill + resizableImageView.contentMode = .ScaleAspectFill applicationWindow.addSubview(resizableImageView) sender.hidden = true @@ -711,10 +721,17 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { width: imageFromView.size.width / scaleFactor, height: imageFromView.size.height / scaleFactor) + if sender.layer.cornerRadius != 0 { + let duration = (animationDuration * Double(animationDamping)) + self.resizableImageView.layer.masksToBounds = true + self.resizableImageView.addCornerRadiusAnimation(sender.layer.cornerRadius, to: 0, duration: duration) + } - UIView.animateWithDuration(animationDuration, - animations: { () -> Void in + UIView.animateWithDuration(animationDuration, delay:0, usingSpringWithDamping:animationDamping, initialSpringVelocity:0, options:.CurveEaseInOut, animations: { () -> Void in + + fadeView.alpha = 1.0 self.resizableImageView.frame = finalImageViewFrame + if self.displayCloseButton == true { self.closeButton.alpha = 1.0 self.closeButton.frame = self.closeButtonShowFrame @@ -741,12 +758,8 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } else { - let fadeView = UIView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)) - fadeView.backgroundColor = .clearColor() - applicationWindow.addSubview(fadeView) - - UIView.animateWithDuration(animationDuration, - animations: { () -> Void in + UIView.animateWithDuration(animationDuration, delay:0, usingSpringWithDamping:animationDamping, initialSpringVelocity:0, options:.CurveEaseInOut, animations: { () -> Void in + fadeView.alpha = 1.0 if self.displayCloseButton == true { self.closeButton.alpha = 1.0 self.closeButton.frame = self.closeButtonShowFrame @@ -773,20 +786,37 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } public func performCloseAnimationWithScrollView(scrollView: SKZoomingScrollView) { + view.hidden = true let fadeView = UIView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)) + let contentOffset = scrollView.contentOffset + let scrollFrame = scrollView.photoImageView.frame + let offsetY = scrollView.center.y - (scrollView.bounds.height/2) + + let frame = CGRect( + x: scrollFrame.origin.x - contentOffset.x, + y: scrollFrame.origin.y + contentOffset.y + offsetY, + width: scrollFrame.width, + height: scrollFrame.height) + fadeView.backgroundColor = .blackColor() fadeView.alpha = 1.0 - applicationWindow.addSubview(fadeView) + applicationWindow.addSubview(fadeView) + resizableImageView.frame = frame resizableImageView.alpha = 1.0 resizableImageView.clipsToBounds = true - resizableImageView.contentMode = .ScaleToFill + resizableImageView.contentMode = .ScaleAspectFill applicationWindow.addSubview(resizableImageView) - UIView.animateWithDuration(animationDuration, - animations: { () -> () in + if let view = senderViewForAnimation where view.layer.cornerRadius != 0 { + let duration = (animationDuration * Double(animationDamping)) + self.resizableImageView.layer.masksToBounds = true + self.resizableImageView.addCornerRadiusAnimation(0, to: view.layer.cornerRadius, duration: duration) + } + + UIView.animateWithDuration(animationDuration, delay:0, usingSpringWithDamping:animationDamping, initialSpringVelocity:0, options:.CurveEaseInOut, animations: { () -> () in fadeView.alpha = 0.0 self.resizableImageView.layer.frame = self.senderViewOriginalFrame }, @@ -987,7 +1017,7 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } } - UIView.animateWithDuration(0.35, + UIView.animateWithDuration(animationDuration, animations: { () -> Void in let alpha: CGFloat = hidden ? 0.0 : 1.0 self.toolBar.alpha = alpha @@ -1184,3 +1214,17 @@ public class SKPhotoBrowser: UIViewController, UIScrollViewDelegate { } } } + +extension UIView +{ + func addCornerRadiusAnimation(from: CGFloat, to: CGFloat, duration: CFTimeInterval) + { + let animation = CABasicAnimation(keyPath:"cornerRadius") + animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.fromValue = from + animation.toValue = to + animation.duration = duration + self.layer.addAnimation(animation, forKey: "cornerRadius") + self.layer.cornerRadius = to + } +} diff --git a/SKPhotoBrowser/SKZoomingScrollView.swift b/SKPhotoBrowser/SKZoomingScrollView.swift index 1ffbcdd..6996603 100644 --- a/SKPhotoBrowser/SKZoomingScrollView.swift +++ b/SKPhotoBrowser/SKZoomingScrollView.swift @@ -18,9 +18,9 @@ public class SKZoomingScrollView: UIScrollView, UIScrollViewDelegate, SKDetectin } } + private(set) var photoImageView: SKDetectingImageView! private weak var photoBrowser: SKPhotoBrowser! private var tapView: SKDetectingView! - private var photoImageView: SKDetectingImageView! private var indicatorView: SKIndicatorView! required public init?(coder aDecoder: NSCoder) { diff --git a/SKPhotoBrowserExample/SKPhotoBrowserExample.xcodeproj/project.pbxproj b/SKPhotoBrowserExample/SKPhotoBrowserExample.xcodeproj/project.pbxproj index 0964c5b..207af69 100644 --- a/SKPhotoBrowserExample/SKPhotoBrowserExample.xcodeproj/project.pbxproj +++ b/SKPhotoBrowserExample/SKPhotoBrowserExample.xcodeproj/project.pbxproj @@ -13,18 +13,18 @@ 8909B5621BC792150060A053 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5611BC792150060A053 /* Assets.xcassets */; }; 8909B5651BC792150060A053 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5631BC792150060A053 /* LaunchScreen.storyboard */; }; 8909B5731BC792AF0060A053 /* SKPhotoBrowser.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8909B5711BC792570060A053 /* SKPhotoBrowser.framework */; }; - 8909B5811BC792DC0060A053 /* image0.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5751BC792DC0060A053 /* image0.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5821BC792DC0060A053 /* image1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5761BC792DC0060A053 /* image1.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5831BC792DC0060A053 /* image10.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5771BC792DC0060A053 /* image10.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5841BC792DC0060A053 /* image12.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5781BC792DC0060A053 /* image12.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5851BC792DC0060A053 /* image2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5791BC792DC0060A053 /* image2.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5861BC792DC0060A053 /* image3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57A1BC792DC0060A053 /* image3.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5871BC792DC0060A053 /* image4.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57B1BC792DC0060A053 /* image4.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5881BC792DC0060A053 /* image5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57C1BC792DC0060A053 /* image5.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B5891BC792DC0060A053 /* image6.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57D1BC792DC0060A053 /* image6.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B58A1BC792DC0060A053 /* image7.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57E1BC792DC0060A053 /* image7.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B58B1BC792DC0060A053 /* image8.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57F1BC792DC0060A053 /* image8.jpg */; settings = {ASSET_TAGS = (); }; }; - 8909B58C1BC792DC0060A053 /* image9.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5801BC792DC0060A053 /* image9.jpg */; settings = {ASSET_TAGS = (); }; }; + 8909B5811BC792DC0060A053 /* image0.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5751BC792DC0060A053 /* image0.jpg */; }; + 8909B5821BC792DC0060A053 /* image1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5761BC792DC0060A053 /* image1.jpg */; }; + 8909B5831BC792DC0060A053 /* image10.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5771BC792DC0060A053 /* image10.jpg */; }; + 8909B5841BC792DC0060A053 /* image12.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5781BC792DC0060A053 /* image12.jpg */; }; + 8909B5851BC792DC0060A053 /* image2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5791BC792DC0060A053 /* image2.jpg */; }; + 8909B5861BC792DC0060A053 /* image3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57A1BC792DC0060A053 /* image3.jpg */; }; + 8909B5871BC792DC0060A053 /* image4.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57B1BC792DC0060A053 /* image4.jpg */; }; + 8909B5881BC792DC0060A053 /* image5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57C1BC792DC0060A053 /* image5.jpg */; }; + 8909B5891BC792DC0060A053 /* image6.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57D1BC792DC0060A053 /* image6.jpg */; }; + 8909B58A1BC792DC0060A053 /* image7.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57E1BC792DC0060A053 /* image7.jpg */; }; + 8909B58B1BC792DC0060A053 /* image8.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B57F1BC792DC0060A053 /* image8.jpg */; }; + 8909B58C1BC792DC0060A053 /* image9.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8909B5801BC792DC0060A053 /* image9.jpg */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ diff --git a/SKPhotoBrowserExample/SKPhotoBrowserExample/Base.lproj/Main.storyboard b/SKPhotoBrowserExample/SKPhotoBrowserExample/Base.lproj/Main.storyboard index b3160f4..c62471d 100644 --- a/SKPhotoBrowserExample/SKPhotoBrowserExample/Base.lproj/Main.storyboard +++ b/SKPhotoBrowserExample/SKPhotoBrowserExample/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -32,7 +32,7 @@ - + diff --git a/SKPhotoBrowserExample/SKPhotoBrowserExample/ViewController.swift b/SKPhotoBrowserExample/SKPhotoBrowserExample/ViewController.swift index 6765a45..86f1fc1 100644 --- a/SKPhotoBrowserExample/SKPhotoBrowserExample/ViewController.swift +++ b/SKPhotoBrowserExample/SKPhotoBrowserExample/ViewController.swift @@ -76,6 +76,7 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection let browser = SKPhotoBrowser(originImage: originImage, photos: images, animatedFromView: cell) browser.initializePageIndex(indexPath.row) browser.delegate = self + browser.bounceAnimation = true // Can hide the action button by setting to false browser.displayAction = true @@ -124,6 +125,8 @@ class ExampleCollectionViewCell: UICollectionViewCell { override func awakeFromNib() { super.awakeFromNib() exampleImageView.image = nil + layer.cornerRadius = 25.0 + layer.masksToBounds = true } override func prepareForReuse() {