From 952acd8e3ca74784b65bf4ac18032555944cc50b Mon Sep 17 00:00:00 2001 From: Spencer Comerford Date: Fri, 5 Dec 2014 10:46:42 -0700 Subject: [PATCH 1/9] Modified to return instance from constructor Also added "show" and "close" methods and additional constructor to better control showing and closing the viewer. --- EXPhotoViewer/EXPhotoViewer.h | 6 ++++- EXPhotoViewer/EXPhotoViewer.m | 43 +++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/EXPhotoViewer/EXPhotoViewer.h b/EXPhotoViewer/EXPhotoViewer.h index 1e5a01a..848d4de 100644 --- a/EXPhotoViewer/EXPhotoViewer.h +++ b/EXPhotoViewer/EXPhotoViewer.h @@ -10,6 +10,10 @@ @interface EXPhotoViewer : UIViewController -+ (void) showImageFrom:(UIImageView*) image; ++ (instancetype)showImageFrom:(UIImageView *)imageView; ++ (instancetype)newViewerFor:(UIImageView *)imageView; + +- (void)show; +- (void)close; @end diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index cdf6f2c..60bb005 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -11,12 +11,12 @@ @interface EXPhotoViewer () @property (nonatomic, retain) UIScrollView *zoomeableScrollView; +@property (nonatomic, retain) UIImageView *originalImageView; @property (nonatomic, retain) UIImageView *theImageView; @property (nonatomic, retain) UIView* tempViewContainer; @property (nonatomic, assign) CGRect originalImageRect; @property (nonatomic, retain) UIViewController* controller; @property (nonatomic, retain) UIViewController* selfController; -@property (nonatomic, retain) UIImageView* originalImage; @end @@ -24,11 +24,23 @@ @interface EXPhotoViewer () @implementation EXPhotoViewer -+ (void) showImageFrom:(UIImageView*) imageView { ++ (instancetype)showImageFrom:(UIImageView *)imageView { + EXPhotoViewer *viewer = [self newViewerFor:imageView]; + + [viewer show]; + + return viewer; +} + ++ (instancetype)newViewerFor:(UIImageView *)imageView { + EXPhotoViewer *viewer = nil; + if (imageView.image) { - EXPhotoViewer* viewer = [EXPhotoViewer new]; - [viewer showImageFrom:imageView]; + viewer = [EXPhotoViewer new]; + viewer.originalImageView = imageView; } + + return viewer; } -(void)loadView { @@ -59,7 +71,10 @@ -(UIViewController *) rootViewController{ return controller; } -- (void) showImageFrom:(UIImageView*) imageView { +- (void)show { + if (self.controller) + return; + UIViewController * controller = [self rootViewController]; self.tempViewContainer = [[UIView alloc] initWithFrame:controller.view.bounds]; @@ -79,8 +94,8 @@ - (void) showImageFrom:(UIImageView*) imageView { [controller.view addSubview:self.view]; - self.theImageView.image = imageView.image; - self.originalImageRect = [imageView convertRect:imageView.bounds toView:self.view]; + self.theImageView.image = self.originalImageView.image; + self.originalImageRect = [self.originalImageView convertRect:self.originalImageView.bounds toView:self.view]; self.theImageView.frame = self.originalImageRect; @@ -99,23 +114,19 @@ - (void) showImageFrom:(UIImageView*) imageView { }]; self.selfController = self; //Stupid ARC I need to do this to avoid being dealloced :P - self.originalImage = imageView; - imageView.image = nil; } -(void) dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; } -- (void)orientationDidChange:(NSNotification *)note -{ +- (void)orientationDidChange:(NSNotification *)note { self.theImageView.frame = [self centeredOnScreenImage:self.theImageView.image]; CGRect newFrame = [self rootViewController].view.bounds; self.tempViewContainer.frame = newFrame; self.view.frame = newFrame; [self adjustScrollInsetsToCenterImage]; - } - (void) onBackgroundTap { @@ -124,7 +135,7 @@ - (void) onBackgroundTap { self.zoomeableScrollView.contentInset = UIEdgeInsetsZero; self.theImageView.frame = absoluteCGRect; - CGRect originalImageRect = [self.originalImage convertRect:self.originalImage.frame toView:self.view]; + CGRect originalImageRect = [self.originalImageView convertRect:self.originalImageView.frame toView:self.view]; //originalImageRect is now scaled down, need to adjust CGFloat scaleBack = 1.0/s_backgroundScale; CGFloat x = originalImageRect.origin.x; @@ -146,7 +157,7 @@ - (void) onBackgroundTap { self.view.backgroundColor = [UIColor clearColor]; self.tempViewContainer.layer.transform = CATransform3DIdentity; }completion:^(BOOL finished) { - self.originalImage.image = self.theImageView.image; + self.originalImageView.image = self.theImageView.image; self.controller.view.backgroundColor = self.tempViewContainer.backgroundColor; for (UIView* subView in self.tempViewContainer.subviews) { [self.controller.view addSubview:subView]; @@ -158,6 +169,10 @@ - (void) onBackgroundTap { self.selfController = nil;//Ok ARC you can kill me now. } +- (void)close { + [self onBackgroundTap]; +} + - (CGRect) centeredOnScreenImage:(UIImage*) image { CGSize imageSize = [self imageSizesizeThatFitsForImage:self.theImageView.image]; CGPoint imageOrigin = CGPointMake(self.view.frame.size.width/2.0 - imageSize.width/2.0, self.view.frame.size.height/2.0 - imageSize.height/2.0); From 14485b2725a918c7725784018ae6a0894cec2c8f Mon Sep 17 00:00:00 2001 From: Spencer Comerford Date: Fri, 5 Dec 2014 11:21:32 -0700 Subject: [PATCH 2/9] Added properties to customize appearance --- EXPhotoViewer/EXPhotoViewer.h | 13 ++++++++++++- EXPhotoViewer/EXPhotoViewer.m | 28 +++++++++++----------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/EXPhotoViewer/EXPhotoViewer.h b/EXPhotoViewer/EXPhotoViewer.h index 848d4de..96b0eca 100644 --- a/EXPhotoViewer/EXPhotoViewer.h +++ b/EXPhotoViewer/EXPhotoViewer.h @@ -8,7 +8,18 @@ #import -@interface EXPhotoViewer : UIViewController +@interface EXPhotoViewer : UIViewController + +/** + * The scale to be applied as transformation to the background. IE, a scall of + * 0.8 would "shrink" the background making it appear inset from the screen edges. + */ +@property (nonatomic) CGFloat backgroundScale; + +/** + * The background color of the screen while image is being viewed. Default is black. + */ +@property (nonatomic, strong) UIColor *backgroundColor; + (instancetype)showImageFrom:(UIImageView *)imageView; + (instancetype)newViewerFor:(UIImageView *)imageView; diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index 60bb005..5b2d8d1 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -20,8 +20,6 @@ @interface EXPhotoViewer () @end -static CGFloat s_backgroundScale = 0.8f; - @implementation EXPhotoViewer + (instancetype)showImageFrom:(UIImageView *)imageView { @@ -38,6 +36,7 @@ + (instancetype)newViewerFor:(UIImageView *)imageView { if (imageView.image) { viewer = [EXPhotoViewer new]; viewer.originalImageView = imageView; + viewer.backgroundScale = 1.0; } return viewer; @@ -104,21 +103,20 @@ - (void)show { [UIView animateWithDuration:0.3 animations:^{ - self.view.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.7]; - self.tempViewContainer.layer.transform = CATransform3DMakeScale(s_backgroundScale, s_backgroundScale, s_backgroundScale); + self.view.backgroundColor = (self.backgroundColor) ? self.backgroundColor : [UIColor blackColor]; + self.tempViewContainer.layer.transform = CATransform3DMakeScale(self.backgroundScale, self.backgroundScale, self.backgroundScale); self.theImageView.frame = [self centeredOnScreenImage:self.theImageView.image]; } completion:^(BOOL finished) { [self adjustScrollInsetsToCenterImage]; - UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onBackgroundTap)]; + UITapGestureRecognizer* tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(close)]; [self.view addGestureRecognizer:tap]; }]; - + self.selfController = self; //Stupid ARC I need to do this to avoid being dealloced :P } --(void) dealloc{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; -} +-(void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];} - (void)orientationDidChange:(NSNotification *)note { self.theImageView.frame = [self centeredOnScreenImage:self.theImageView.image]; @@ -129,7 +127,7 @@ - (void)orientationDidChange:(NSNotification *)note { [self adjustScrollInsetsToCenterImage]; } -- (void) onBackgroundTap { +- (void)close { CGRect absoluteCGRect = [self.view convertRect:self.theImageView.frame fromView:self.theImageView.superview]; self.zoomeableScrollView.contentOffset = CGPointZero; self.zoomeableScrollView.contentInset = UIEdgeInsetsZero; @@ -137,7 +135,7 @@ - (void) onBackgroundTap { CGRect originalImageRect = [self.originalImageView convertRect:self.originalImageView.frame toView:self.view]; //originalImageRect is now scaled down, need to adjust - CGFloat scaleBack = 1.0/s_backgroundScale; + CGFloat scaleBack = 1.0/self.backgroundScale; CGFloat x = originalImageRect.origin.x; CGFloat y = originalImageRect.origin.y; CGFloat maxX = self.view.frame.size.width; @@ -148,8 +146,8 @@ - (void) onBackgroundTap { originalImageRect.origin.x = x; originalImageRect.origin.y = y; - originalImageRect.size.width *= 1.0/s_backgroundScale; - originalImageRect.size.height *= 1.0/s_backgroundScale; + originalImageRect.size.width *= 1.0/self.backgroundScale; + originalImageRect.size.height *= 1.0/self.backgroundScale; //done scaling [UIView animateWithDuration:0.3 animations:^{ @@ -169,10 +167,6 @@ - (void) onBackgroundTap { self.selfController = nil;//Ok ARC you can kill me now. } -- (void)close { - [self onBackgroundTap]; -} - - (CGRect) centeredOnScreenImage:(UIImage*) image { CGSize imageSize = [self imageSizesizeThatFitsForImage:self.theImageView.image]; CGPoint imageOrigin = CGPointMake(self.view.frame.size.width/2.0 - imageSize.width/2.0, self.view.frame.size.height/2.0 - imageSize.height/2.0); From 94cbba4559e2538ce7d3d87ed2a0e319ef8038c3 Mon Sep 17 00:00:00 2001 From: Spencer Comerford Date: Fri, 5 Dec 2014 11:34:02 -0700 Subject: [PATCH 3/9] Changed image sizing to fit to screen size --- EXPhotoViewer.podspec | 8 ++++---- EXPhotoViewer/EXPhotoViewer.m | 9 ++++----- .../EXPhotoViewerDemo/woman/1_woman.jpg | Bin 38743 -> 17491 bytes 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/EXPhotoViewer.podspec b/EXPhotoViewer.podspec index 4c75df1..62021ef 100644 --- a/EXPhotoViewer.podspec +++ b/EXPhotoViewer.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "EXPhotoViewer" - s.version = "1.0.0" + s.version = "1.1.3" s.summary = "A one liner full screen photo viewer" s.description = <<-DESC @@ -23,8 +23,8 @@ Then if for example "anImageView" contains the image you would like to show, jus [EXPhotoViewer showImageFrom:anImageView]; DESC - s.homepage = "https://github.com/Julioacarrettoni/EXPhotoViewer" - s.screenshots = "https://raw.githubusercontent.com/Julioacarrettoni/EXPhotoViewer/master/screenshots/iphone_screenshot_2.png", "https://raw.githubusercontent.com/Julioacarrettoni/EXPhotoViewer/master/screenshots/iphone_screenshot_1.png" + s.homepage = "https://github.com/ShowMobile/EXPhotoViewer" + s.screenshots = "https://raw.githubusercontent.com/ShowMobile/EXPhotoViewer/master/screenshots/iphone_screenshot_2.png", "https://raw.githubusercontent.com/ShowMobile/EXPhotoViewer/master/screenshots/iphone_screenshot_1.png" s.license = { :type => 'MIT', :file => 'LICENSE' } @@ -35,7 +35,7 @@ Then if for example "anImageView" contains the image you would like to show, jus s.platform = :ios s.platform = :ios, '6.0' - s.source = { :git => "https://github.com/Julioacarrettoni/EXPhotoViewer.git", :tag => "1.0.0" } + s.source = { :git => "https://github.com/ShowMobile/EXPhotoViewer.git", :tag => "1.1.3" } s.source_files = 'EXPhotoViewer/*.{h,m}' s.resource = 'EXPhotoViewer/*.{xib}' diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index 5b2d8d1..416a36d 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -61,7 +61,7 @@ -(void)loadView { self.theImageView = imageView; } --(UIViewController *) rootViewController{ +-(UIViewController *)rootViewController { UIViewController* controller = [UIApplication sharedApplication].keyWindow.rootViewController; if ([controller presentedViewController]) { @@ -167,19 +167,18 @@ - (void)close { self.selfController = nil;//Ok ARC you can kill me now. } -- (CGRect) centeredOnScreenImage:(UIImage*) image { +- (CGRect)centeredOnScreenImage:(UIImage*) image { CGSize imageSize = [self imageSizesizeThatFitsForImage:self.theImageView.image]; CGPoint imageOrigin = CGPointMake(self.view.frame.size.width/2.0 - imageSize.width/2.0, self.view.frame.size.height/2.0 - imageSize.height/2.0); return CGRectMake(imageOrigin.x, imageOrigin.y, imageSize.width, imageSize.height); } -- (CGSize) imageSizesizeThatFitsForImage:(UIImage*) image { +- (CGSize)imageSizesizeThatFitsForImage:(UIImage*) image { if (!image) return CGSizeZero; CGSize imageSize = image.size; CGFloat ratio = MIN(self.view.frame.size.width/imageSize.width, self.view.frame.size.height/imageSize.height); - ratio = MIN(ratio, 1.0);//If the image is smaller than the screen let's not make it bigger return CGSizeMake(imageSize.width*ratio, imageSize.height*ratio); } @@ -188,7 +187,7 @@ - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.theImageView; } -- (void) adjustScrollInsetsToCenterImage { +- (void)adjustScrollInsetsToCenterImage { CGSize imageSize = [self imageSizesizeThatFitsForImage:self.theImageView.image]; self.zoomeableScrollView.zoomScale = 1.0; self.theImageView.frame = CGRectMake(0, 0, imageSize.width, imageSize.height); diff --git a/EXPhotoViewerDemo/EXPhotoViewerDemo/woman/1_woman.jpg b/EXPhotoViewerDemo/EXPhotoViewerDemo/woman/1_woman.jpg index 9bf4c9681743a338c92fd7a872fadf8c2c51e365..9a445424337c94c1815488f57ebe57abb3df7afa 100644 GIT binary patch literal 17491 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 O$L}q8VR;O@pZ_1U7Ys-M literal 38743 zcmZ6x19Tuk*DczyZQGdGwrx#pb7D)f*008;AfX_`p6o3Q=2ZsQMgn)pAf&9ARpdlfl;oxCm;b39m zk>UUA{x|xchyOSHPbMHxP*4c)2-wKT*yxCei0J>8lOxMC5HRo5+|FG3XF=e#RZ(=+@)#W?PV_KP*tgYIsVp@S-k}di% zpq;cd-<=ua+1{aPq=NvudxkK^@iCV%)nI7j(ey1VF(aTqHzCShy#ica7$CLOrqOV@ zI9r`u9h_=S7c=+e*JWp|3B%LW89LWln|9u4|53sW%N3adUols1fKjPgs{^&#Z7vgR zuV0I+wRCI2Am1HtVxqAaEuNokA)j&ed;geX(p`~70>gT-AK?dVu@YnNj?;z><9R1t_yllsOMo*G?F`VI0~o<1mg>_rU2WeiWf_0?9Md&z2% zT+ZnAqJ{NtlY{|^n4D17Dp;KTg`TEbyG~N{R0fRuJZ5K52t#;wVY2nbwMJ%50eu6R zP{VV(oGnjc-Q_bL-vmiK##nwh9tmIBZ7m6olxi@s4OA>l0JODE)m z^TEbuWff9<8!nsEXr8cziajJQJ;7`GPK#5yUX3_=8xEY|b~FO|e4z#UJtd~?`)j6dX(vGDVS!no(_-7 z%ZE|`%-DQO$IXqild-TO%N71EM$S(&;rOq#Xkqqwc1et~!biv;Dpqbv_$Z8cf;7(Q zMlM3qz^O~xs|B+AtNmoj<|dmNJNFP*8~$w0p;mdvkB82DXZ=>wSkmo7RI>5xqIqvk znwKXO7bx=5X@OGd&HGI+FGewJn)vvM!GpK`%IdmDeY~9h8BOfK(#dvtDrcGjMqT{c zTo=jX3%!ZX{LbZvPTZ&JSn*~|F|uH?l;3SOo|_}*|D;pLODO@mTof&Cy^!P)keSgO z&*2)8oKz=9SAuWK?LLq6mU>w-#SrX@SqDB(w9|fJnu`i53F|?~VYCw53Mw*6(P}=0 zzfPz(OYl0kiR4>7zb`d7<2T5ITM!aqoV?8k*VdlniqjC1Vhhz5iO%$oiBKvJ-E`3h z%JRx8=AXCP8LTbTQzwpRFABxN&+yK83deV26+WQSm@>mV`V^B+jncqSD&P4tpH$BB z%;c;Z&D&XOH@k0uM|;zVr)y3f`aDIJ`tg5rIt@uDM7E?cYn%~JCzmECg5R?WN^5cL z`1k}=`Vp+>(V=aq$f!gh{Yg%;dU=f>uM3_$A}GzHQCQN)ZnH{hSf*c|QcE>@QfuW; zQyQV>Z7owZuw&d0XU$4@JhOUJ4-Qx6uDlTc8QZ7lW9C?^CMOqj%BH_8;_<+h_MUbu zd(L>HXA{}Y>(S%ZNVp>T``0#S#~kMPx(J+982ouUOwWLyi1h66@T78}ywPh#5_1qb z4GNab9v1jzGG`eXhB2d*`U&VRU!G}~pL~%0D%V|o@aAtXv24;-k&))@EE3FV16^8Z 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 From 7b712bd1e075d7b71d0991ea476485c8c4fb00e3 Mon Sep 17 00:00:00 2001 From: Spencer Comerford Date: Fri, 5 Dec 2014 11:59:42 -0700 Subject: [PATCH 4/9] Fixed constructor to allow subclassing Added boolean to indicate closing animation is already occuring, preventing duplicate calls to close. --- EXPhotoViewer.podspec | 4 +- EXPhotoViewer/EXPhotoViewer.h | 2 + EXPhotoViewer/EXPhotoViewer.m | 83 +++++++++++++++++++---------------- 3 files changed, 49 insertions(+), 40 deletions(-) diff --git a/EXPhotoViewer.podspec b/EXPhotoViewer.podspec index 62021ef..52d16ee 100644 --- a/EXPhotoViewer.podspec +++ b/EXPhotoViewer.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "EXPhotoViewer" - s.version = "1.1.3" + s.version = "1.1.4" s.summary = "A one liner full screen photo viewer" s.description = <<-DESC @@ -35,7 +35,7 @@ Then if for example "anImageView" contains the image you would like to show, jus s.platform = :ios s.platform = :ios, '6.0' - s.source = { :git => "https://github.com/ShowMobile/EXPhotoViewer.git", :tag => "1.1.3" } + s.source = { :git => "https://github.com/ShowMobile/EXPhotoViewer.git", :tag => "1.1.4" } s.source_files = 'EXPhotoViewer/*.{h,m}' s.resource = 'EXPhotoViewer/*.{xib}' diff --git a/EXPhotoViewer/EXPhotoViewer.h b/EXPhotoViewer/EXPhotoViewer.h index 96b0eca..4eca365 100644 --- a/EXPhotoViewer/EXPhotoViewer.h +++ b/EXPhotoViewer/EXPhotoViewer.h @@ -21,6 +21,8 @@ */ @property (nonatomic, strong) UIColor *backgroundColor; +@property (atomic, readonly) BOOL isClosing; + + (instancetype)showImageFrom:(UIImageView *)imageView; + (instancetype)newViewerFor:(UIImageView *)imageView; diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index 416a36d..542ba51 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -17,6 +17,7 @@ @interface EXPhotoViewer () @property (nonatomic, assign) CGRect originalImageRect; @property (nonatomic, retain) UIViewController* controller; @property (nonatomic, retain) UIViewController* selfController; +@property (atomic, readwrite) BOOL isClosing; @end @@ -34,7 +35,7 @@ + (instancetype)newViewerFor:(UIImageView *)imageView { EXPhotoViewer *viewer = nil; if (imageView.image) { - viewer = [EXPhotoViewer new]; + viewer = [[self alloc] init]; viewer.originalImageView = imageView; viewer.backgroundScale = 1.0; } @@ -128,43 +129,49 @@ - (void)orientationDidChange:(NSNotification *)note { } - (void)close { - CGRect absoluteCGRect = [self.view convertRect:self.theImageView.frame fromView:self.theImageView.superview]; - self.zoomeableScrollView.contentOffset = CGPointZero; - self.zoomeableScrollView.contentInset = UIEdgeInsetsZero; - self.theImageView.frame = absoluteCGRect; - - CGRect originalImageRect = [self.originalImageView convertRect:self.originalImageView.frame toView:self.view]; - //originalImageRect is now scaled down, need to adjust - CGFloat scaleBack = 1.0/self.backgroundScale; - CGFloat x = originalImageRect.origin.x; - CGFloat y = originalImageRect.origin.y; - CGFloat maxX = self.view.frame.size.width; - CGFloat maxY = self.view.frame.size.height; - - y = (y - (maxY / 2.0) ) * scaleBack + (maxY / 2.0); - x= (x - (maxX / 2.0) ) * scaleBack + (maxX / 2.0); - originalImageRect.origin.x = x; - originalImageRect.origin.y = y; - - originalImageRect.size.width *= 1.0/self.backgroundScale; - originalImageRect.size.height *= 1.0/self.backgroundScale; - //done scaling - - [UIView animateWithDuration:0.3 animations:^{ - self.theImageView.frame = originalImageRect; - self.view.backgroundColor = [UIColor clearColor]; - self.tempViewContainer.layer.transform = CATransform3DIdentity; - }completion:^(BOOL finished) { - self.originalImageView.image = self.theImageView.image; - self.controller.view.backgroundColor = self.tempViewContainer.backgroundColor; - for (UIView* subView in self.tempViewContainer.subviews) { - [self.controller.view addSubview:subView]; - } - [self.view removeFromSuperview]; - [self.tempViewContainer removeFromSuperview]; - }]; - - self.selfController = nil;//Ok ARC you can kill me now. + if (!self.isClosing) { + self.isClosing = YES; + + CGRect absoluteCGRect = [self.view convertRect:self.theImageView.frame fromView:self.theImageView.superview]; + self.zoomeableScrollView.contentOffset = CGPointZero; + self.zoomeableScrollView.contentInset = UIEdgeInsetsZero; + self.theImageView.frame = absoluteCGRect; + + CGRect originalImageRect = [self.originalImageView convertRect:self.originalImageView.frame toView:self.view]; + //originalImageRect is now scaled down, need to adjust + CGFloat scaleBack = 1.0/self.backgroundScale; + CGFloat x = originalImageRect.origin.x; + CGFloat y = originalImageRect.origin.y; + CGFloat maxX = self.view.frame.size.width; + CGFloat maxY = self.view.frame.size.height; + + y = (y - (maxY / 2.0) ) * scaleBack + (maxY / 2.0); + x= (x - (maxX / 2.0) ) * scaleBack + (maxX / 2.0); + originalImageRect.origin.x = x; + originalImageRect.origin.y = y; + + originalImageRect.size.width *= 1.0/self.backgroundScale; + originalImageRect.size.height *= 1.0/self.backgroundScale; + //done scaling + + [UIView animateWithDuration:0.3 animations:^{ + self.theImageView.frame = originalImageRect; + self.view.backgroundColor = [UIColor clearColor]; + self.tempViewContainer.layer.transform = CATransform3DIdentity; + }completion:^(BOOL finished) { + self.originalImageView.image = self.theImageView.image; + self.controller.view.backgroundColor = self.tempViewContainer.backgroundColor; + for (UIView* subView in self.tempViewContainer.subviews) { + [self.controller.view addSubview:subView]; + } + [self.view removeFromSuperview]; + [self.tempViewContainer removeFromSuperview]; + + self.isClosing = NO; + }]; + + self.selfController = nil;//Ok ARC you can kill me now. + } } - (CGRect)centeredOnScreenImage:(UIImage*) image { From ae198017c8cba6c29dbae11ffd8eedf9489996a8 Mon Sep 17 00:00:00 2001 From: Spencer Comerford Date: Fri, 5 Dec 2014 12:28:54 -0700 Subject: [PATCH 5/9] Reverted podspec and corrected errors Added the correct version number, and removed unneeded resource definition line. Spec now passes `pod spec lint`. --- EXPhotoViewer.podspec | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/EXPhotoViewer.podspec b/EXPhotoViewer.podspec index 52d16ee..8be2d64 100644 --- a/EXPhotoViewer.podspec +++ b/EXPhotoViewer.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "EXPhotoViewer" - s.version = "1.1.4" + s.version = "1.1.2" s.summary = "A one liner full screen photo viewer" s.description = <<-DESC @@ -23,8 +23,8 @@ Then if for example "anImageView" contains the image you would like to show, jus [EXPhotoViewer showImageFrom:anImageView]; DESC - s.homepage = "https://github.com/ShowMobile/EXPhotoViewer" - s.screenshots = "https://raw.githubusercontent.com/ShowMobile/EXPhotoViewer/master/screenshots/iphone_screenshot_2.png", "https://raw.githubusercontent.com/ShowMobile/EXPhotoViewer/master/screenshots/iphone_screenshot_1.png" + s.homepage = "https://github.com/Julioacarrettoni/EXPhotoViewer" + s.screenshots = "https://raw.githubusercontent.com/Julioacarrettoni/EXPhotoViewer/master/screenshots/iphone_screenshot_2.png", "https://raw.githubusercontent.com/Julioacarrettoni/EXPhotoViewer/master/screenshots/iphone_screenshot_1.png" s.license = { :type => 'MIT', :file => 'LICENSE' } @@ -35,10 +35,9 @@ Then if for example "anImageView" contains the image you would like to show, jus s.platform = :ios s.platform = :ios, '6.0' - s.source = { :git => "https://github.com/ShowMobile/EXPhotoViewer.git", :tag => "1.1.4" } + s.source = { :git => "https://github.com/Julioacarrettoni/EXPhotoViewer.git", :tag => "1.1.2" } s.source_files = 'EXPhotoViewer/*.{h,m}' - s.resource = 'EXPhotoViewer/*.{xib}' s.requires_arc = true From 555096529615b1dd886ccb3dbaf83b5a5b8577e6 Mon Sep 17 00:00:00 2001 From: Spencer Comerford Date: Fri, 5 Dec 2014 12:54:49 -0700 Subject: [PATCH 6/9] Simplified close method and fixed issue with original image view rect --- EXPhotoViewer/EXPhotoViewer.m | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index 542ba51..0a354d7 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -137,25 +137,8 @@ - (void)close { self.zoomeableScrollView.contentInset = UIEdgeInsetsZero; self.theImageView.frame = absoluteCGRect; - CGRect originalImageRect = [self.originalImageView convertRect:self.originalImageView.frame toView:self.view]; - //originalImageRect is now scaled down, need to adjust - CGFloat scaleBack = 1.0/self.backgroundScale; - CGFloat x = originalImageRect.origin.x; - CGFloat y = originalImageRect.origin.y; - CGFloat maxX = self.view.frame.size.width; - CGFloat maxY = self.view.frame.size.height; - - y = (y - (maxY / 2.0) ) * scaleBack + (maxY / 2.0); - x= (x - (maxX / 2.0) ) * scaleBack + (maxX / 2.0); - originalImageRect.origin.x = x; - originalImageRect.origin.y = y; - - originalImageRect.size.width *= 1.0/self.backgroundScale; - originalImageRect.size.height *= 1.0/self.backgroundScale; - //done scaling - [UIView animateWithDuration:0.3 animations:^{ - self.theImageView.frame = originalImageRect; + self.theImageView.frame = self.originalImageRect; self.view.backgroundColor = [UIColor clearColor]; self.tempViewContainer.layer.transform = CATransform3DIdentity; }completion:^(BOOL finished) { @@ -169,7 +152,7 @@ - (void)close { self.isClosing = NO; }]; - + self.selfController = nil;//Ok ARC you can kill me now. } } From 6e057195bcbb8f27cd416d6654d4f87a087c1b9e Mon Sep 17 00:00:00 2001 From: Boaz Ackerman Date: Wed, 28 Jan 2015 16:55:32 +0200 Subject: [PATCH 7/9] making EXPhotoViewer behave nicely with AspectFit --- EXPhotoViewer/EXPhotoViewer.m | 1 + 1 file changed, 1 insertion(+) diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index 0a354d7..c7eec7c 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -98,6 +98,7 @@ - (void)show { self.originalImageRect = [self.originalImageView convertRect:self.originalImageView.bounds toView:self.view]; self.theImageView.frame = self.originalImageRect; + self.theImageView.contentMode = self.originalImageView.contentMode; //listen to the orientation change notification [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; From 96b2779f97ad0fb9ed997d47cee44aa82a323e63 Mon Sep 17 00:00:00 2001 From: Boaz Ackerman Date: Wed, 28 Jan 2015 22:19:45 +0200 Subject: [PATCH 8/9] moved to loadView --- EXPhotoViewer/EXPhotoViewer.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index c7eec7c..a88941d 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -58,6 +58,7 @@ -(void)loadView { UIImageView* imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.clipsToBounds = YES; + imageView.contentMode = self.originalImageView.contentMode; [self.zoomeableScrollView addSubview: imageView]; self.theImageView = imageView; } @@ -98,7 +99,6 @@ - (void)show { self.originalImageRect = [self.originalImageView convertRect:self.originalImageView.bounds toView:self.view]; self.theImageView.frame = self.originalImageRect; - self.theImageView.contentMode = self.originalImageView.contentMode; //listen to the orientation change notification [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; From 7c15262fb25bc38f4be46714df09ea5b187fda47 Mon Sep 17 00:00:00 2001 From: Boaz Ackerman Date: Wed, 28 Jan 2015 22:26:25 +0200 Subject: [PATCH 9/9] deleting irrelevant old line --- EXPhotoViewer/EXPhotoViewer.m | 1 - 1 file changed, 1 deletion(-) diff --git a/EXPhotoViewer/EXPhotoViewer.m b/EXPhotoViewer/EXPhotoViewer.m index a88941d..99775d8 100644 --- a/EXPhotoViewer/EXPhotoViewer.m +++ b/EXPhotoViewer/EXPhotoViewer.m @@ -56,7 +56,6 @@ -(void)loadView { self.zoomeableScrollView = scrollView; UIImageView* imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; - imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.clipsToBounds = YES; imageView.contentMode = self.originalImageView.contentMode; [self.zoomeableScrollView addSubview: imageView];