├── .gitignore ├── PreviewImageView ├── PreviewImageView.h └── PreviewImageView.m ├── PreviewImageViewDemo ├── PreviewImageViewDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── kingzwt.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── kingzwt.xcuserdatad │ │ └── xcschemes │ │ └── PreviewImageViewDemo.xcscheme ├── PreviewImageViewDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── Main.storyboard │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── PreviewImageView.h │ ├── PreviewImageView.m │ ├── PreviewImageViewDemo-Info.plist │ ├── PreviewImageViewDemo-Prefix.pch │ ├── ViewController.h │ ├── ViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── main.m │ └── test.png └── PreviewImageViewDemoTests │ ├── PreviewImageViewDemoTests-Info.plist │ ├── PreviewImageViewDemoTests.m │ └── en.lproj │ └── InfoPlist.strings └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | #Created by http://www.gitignore.io 2 | 3 | ### Xcode ### 4 | build 5 | *.xcodeproj/* 6 | !*.xcodeproj/project.pbxproj 7 | !*.xcworkspace/contents.xcworkspacedata 8 | 9 | 10 | ### Objective-C ### 11 | # OS X 12 | .DS_Store 13 | 14 | # Xcode 15 | build/ 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata 25 | *.xccheckout 26 | profile 27 | *.moved-aside 28 | DerivedData 29 | *.hmap 30 | *.ipa 31 | 32 | # CocoaPods 33 | Pods 34 | -------------------------------------------------------------------------------- /PreviewImageView/PreviewImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewPhotoView.h 3 | // 4 | // 5 | // Created by Joywii on 13-10-16. 6 | // Copyright (c) 2013年 Joywii. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PreviewImageView : UIView 12 | 13 | + (void)showPreviewImage:(UIImage *)image startImageFrame:(CGRect)startImageFrame inView:(UIView *)inView viewFrame:(CGRect)viewFrame; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PreviewImageView/PreviewImageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewPhotoView.m 3 | // 4 | // 5 | // Created by Joywii on 13-10-16. 6 | // Copyright (c) 2013年 Joywii. All rights reserved. 7 | // 8 | 9 | #import "PreviewImageView.h" 10 | #import 11 | #import 12 | 13 | @interface PreviewImageView () 14 | 15 | @property (nonatomic,strong) UIView *contentView; 16 | @property (nonatomic,strong) UIImageView *photoImageView; 17 | @property (nonatomic,strong) NSValue *starRectValue; 18 | @property (nonatomic,strong) NSValue *imageRectValue; 19 | 20 | @end 21 | 22 | @implementation PreviewImageView 23 | 24 | + (void)showPreviewImage:(UIImage *)image startImageFrame:(CGRect)startImageFrame inView:(UIView *)inView viewFrame:(CGRect)viewFrame 25 | { 26 | PreviewImageView *preImageView = [[PreviewImageView alloc] initWithFrame:viewFrame withImage:image startFrame:startImageFrame]; 27 | [inView addSubview:preImageView]; 28 | } 29 | - (id)initWithFrame:(CGRect)frame withImage:(UIImage *)image startFrame:(CGRect)startFrame 30 | { 31 | self = [super initWithFrame:frame]; 32 | if (self) 33 | { 34 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 35 | self.opaque = YES; 36 | 37 | self.starRectValue = [NSValue valueWithCGRect:startFrame]; 38 | 39 | self.contentView = [[UIView alloc] initWithFrame:startFrame]; 40 | self.contentView.backgroundColor = [UIColor clearColor]; 41 | self.contentView.userInteractionEnabled = YES; 42 | self.contentView.clipsToBounds = YES; 43 | self.contentView.layer.masksToBounds = YES; 44 | self.contentView.layer.cornerRadius = 3.0; 45 | [self addSubview:self.contentView]; 46 | 47 | CGRect imageFrame = startFrame; 48 | imageFrame.origin.x = 0; 49 | imageFrame.origin.y = 0; 50 | self.imageRectValue = [NSValue valueWithCGRect:imageFrame]; 51 | 52 | self.photoImageView = [[UIImageView alloc] initWithFrame:imageFrame]; 53 | self.photoImageView.contentMode = UIViewContentModeScaleAspectFit; 54 | self.photoImageView.image = image; 55 | self.photoImageView.backgroundColor = [UIColor clearColor]; 56 | self.photoImageView.userInteractionEnabled = YES; 57 | [self.contentView addSubview:self.photoImageView]; 58 | 59 | [self addTapPressGestureRecognizer]; 60 | [self addLongPressGestureRecognizer]; 61 | 62 | [UIView beginAnimations:@"backgroundcolor" context:nil]; 63 | [UIView setAnimationDuration:0.1]; 64 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 65 | self.backgroundColor = [UIColor blackColor]; 66 | [UIView commitAnimations]; 67 | 68 | [self startShowAnimation]; 69 | } 70 | return self; 71 | } 72 | - (void)handleTapView:(UIGestureRecognizer *)gestureRecognizer 73 | { 74 | [self startHideAnimation]; 75 | [self performSelector:@selector(hide) withObject:nil afterDelay:0.4]; 76 | } 77 | - (void)hide 78 | { 79 | [self removeFromSuperview]; 80 | } 81 | - (void)startShowAnimation 82 | { 83 | [UIView beginAnimations:@"scaleImageShow" context:nil]; 84 | [UIView setAnimationDelegate:self]; 85 | [UIView setAnimationDuration:0.4]; 86 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 87 | self.photoImageView.frame = self.bounds; 88 | self.contentView.frame = self.bounds; 89 | [UIView commitAnimations]; 90 | } 91 | - (void)startHideAnimation 92 | { 93 | [UIView beginAnimations:@"scaleImageHide" context:nil]; 94 | [UIView setAnimationDelegate:self]; 95 | [UIView setAnimationDuration:0.4]; 96 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 97 | self.photoImageView.frame = [self.imageRectValue CGRectValue]; 98 | self.contentView.frame = [self.starRectValue CGRectValue]; 99 | self.backgroundColor = [UIColor clearColor]; 100 | [UIView commitAnimations]; 101 | } 102 | - (void)addTapPressGestureRecognizer 103 | { 104 | UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] init]; 105 | 106 | tapGR.cancelsTouchesInView = NO; 107 | tapGR.delaysTouchesBegan = NO; 108 | tapGR.delaysTouchesEnded = NO; 109 | tapGR.numberOfTapsRequired = 1; 110 | tapGR.numberOfTouchesRequired = 1; 111 | 112 | [tapGR addTarget:self action:@selector(handleTapView:)]; 113 | [self addGestureRecognizer:tapGR]; 114 | } 115 | - (void)addLongPressGestureRecognizer 116 | { 117 | UILongPressGestureRecognizer *longPressGR = 118 | [[UILongPressGestureRecognizer alloc] initWithTarget:self 119 | action:@selector(handleLongPress:)]; 120 | 121 | [longPressGR setMinimumPressDuration:0.4]; 122 | [self addGestureRecognizer:longPressGR]; 123 | } 124 | 125 | - (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer 126 | { 127 | if (gestureRecognizer.state == UIGestureRecognizerStateBegan) 128 | { 129 | UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:nil 130 | delegate:self 131 | cancelButtonTitle:@"取消" 132 | destructiveButtonTitle:@"保存到相册" 133 | otherButtonTitles:nil]; 134 | action.actionSheetStyle = UIActionSheetStyleDefault; 135 | action.tag = 123456; 136 | 137 | [action showInView:self]; 138 | } 139 | } 140 | #pragma mark - UIActionSheetDelegate 141 | - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 142 | { 143 | if(actionSheet.tag == 123456 && buttonIndex == 0) 144 | { 145 | if (self.photoImageView.image) 146 | { 147 | UIImageWriteToSavedPhotosAlbum(self.photoImageView.image,self,@selector(image:didFinishSavingWithError:contextInfo:),nil); 148 | } 149 | else 150 | { 151 | NSLog(@"image is nil"); 152 | } 153 | } 154 | } 155 | -(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 156 | { 157 | if (error != NULL) 158 | { 159 | NSLog(@"%@",error); 160 | } 161 | else 162 | { 163 | NSLog(@"save success!"); 164 | } 165 | } 166 | @end 167 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 456E8C9518D93EEE00C5AC4A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 456E8C9418D93EEE00C5AC4A /* Foundation.framework */; }; 11 | 456E8C9718D93EEE00C5AC4A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 456E8C9618D93EEE00C5AC4A /* CoreGraphics.framework */; }; 12 | 456E8C9918D93EEE00C5AC4A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 456E8C9818D93EEE00C5AC4A /* UIKit.framework */; }; 13 | 456E8C9F18D93EEE00C5AC4A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 456E8C9D18D93EEE00C5AC4A /* InfoPlist.strings */; }; 14 | 456E8CA118D93EEE00C5AC4A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 456E8CA018D93EEE00C5AC4A /* main.m */; }; 15 | 456E8CA518D93EEE00C5AC4A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 456E8CA418D93EEE00C5AC4A /* AppDelegate.m */; }; 16 | 456E8CA818D93EEE00C5AC4A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 456E8CA618D93EEE00C5AC4A /* Main.storyboard */; }; 17 | 456E8CAB18D93EEE00C5AC4A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 456E8CAA18D93EEE00C5AC4A /* ViewController.m */; }; 18 | 456E8CAD18D93EEE00C5AC4A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 456E8CAC18D93EEE00C5AC4A /* Images.xcassets */; }; 19 | 456E8CB418D93EEE00C5AC4A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 456E8CB318D93EEE00C5AC4A /* XCTest.framework */; }; 20 | 456E8CB518D93EEE00C5AC4A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 456E8C9418D93EEE00C5AC4A /* Foundation.framework */; }; 21 | 456E8CB618D93EEE00C5AC4A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 456E8C9818D93EEE00C5AC4A /* UIKit.framework */; }; 22 | 456E8CBE18D93EEE00C5AC4A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 456E8CBC18D93EEE00C5AC4A /* InfoPlist.strings */; }; 23 | 456E8CC018D93EEE00C5AC4A /* PreviewImageViewDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 456E8CBF18D93EEE00C5AC4A /* PreviewImageViewDemoTests.m */; }; 24 | 456E8CCC18D93F3D00C5AC4A /* PreviewImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 456E8CCB18D93F3D00C5AC4A /* PreviewImageView.m */; }; 25 | 45A3A72F18D944FC002A17F4 /* test.png in Resources */ = {isa = PBXBuildFile; fileRef = 45A3A72E18D944FC002A17F4 /* test.png */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 456E8CB718D93EEE00C5AC4A /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 456E8C8918D93EEE00C5AC4A /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 456E8C9018D93EEE00C5AC4A; 34 | remoteInfo = PreviewImageViewDemo; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 456E8C9118D93EEE00C5AC4A /* PreviewImageViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PreviewImageViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 456E8C9418D93EEE00C5AC4A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | 456E8C9618D93EEE00C5AC4A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 42 | 456E8C9818D93EEE00C5AC4A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 43 | 456E8C9C18D93EEE00C5AC4A /* PreviewImageViewDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PreviewImageViewDemo-Info.plist"; sourceTree = ""; }; 44 | 456E8C9E18D93EEE00C5AC4A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 45 | 456E8CA018D93EEE00C5AC4A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 456E8CA218D93EEE00C5AC4A /* PreviewImageViewDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PreviewImageViewDemo-Prefix.pch"; sourceTree = ""; }; 47 | 456E8CA318D93EEE00C5AC4A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 48 | 456E8CA418D93EEE00C5AC4A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 49 | 456E8CA718D93EEE00C5AC4A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 50 | 456E8CA918D93EEE00C5AC4A /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 51 | 456E8CAA18D93EEE00C5AC4A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 52 | 456E8CAC18D93EEE00C5AC4A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 53 | 456E8CB218D93EEE00C5AC4A /* PreviewImageViewDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PreviewImageViewDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 456E8CB318D93EEE00C5AC4A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 55 | 456E8CBB18D93EEE00C5AC4A /* PreviewImageViewDemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PreviewImageViewDemoTests-Info.plist"; sourceTree = ""; }; 56 | 456E8CBD18D93EEE00C5AC4A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 57 | 456E8CBF18D93EEE00C5AC4A /* PreviewImageViewDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PreviewImageViewDemoTests.m; sourceTree = ""; }; 58 | 456E8CCA18D93F3D00C5AC4A /* PreviewImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PreviewImageView.h; path = PreviewImageViewDemo/PreviewImageView.h; sourceTree = ""; }; 59 | 456E8CCB18D93F3D00C5AC4A /* PreviewImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PreviewImageView.m; path = PreviewImageViewDemo/PreviewImageView.m; sourceTree = ""; }; 60 | 45A3A72E18D944FC002A17F4 /* test.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = test.png; sourceTree = ""; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | 456E8C8E18D93EEE00C5AC4A /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 456E8C9718D93EEE00C5AC4A /* CoreGraphics.framework in Frameworks */, 69 | 456E8C9918D93EEE00C5AC4A /* UIKit.framework in Frameworks */, 70 | 456E8C9518D93EEE00C5AC4A /* Foundation.framework in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 456E8CAF18D93EEE00C5AC4A /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | 456E8CB418D93EEE00C5AC4A /* XCTest.framework in Frameworks */, 79 | 456E8CB618D93EEE00C5AC4A /* UIKit.framework in Frameworks */, 80 | 456E8CB518D93EEE00C5AC4A /* Foundation.framework in Frameworks */, 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXFrameworksBuildPhase section */ 85 | 86 | /* Begin PBXGroup section */ 87 | 456E8C8818D93EEE00C5AC4A = { 88 | isa = PBXGroup; 89 | children = ( 90 | 456E8CC918D93F2800C5AC4A /* PreviewImageView */, 91 | 456E8C9A18D93EEE00C5AC4A /* PreviewImageViewDemo */, 92 | 456E8CB918D93EEE00C5AC4A /* PreviewImageViewDemoTests */, 93 | 456E8C9318D93EEE00C5AC4A /* Frameworks */, 94 | 456E8C9218D93EEE00C5AC4A /* Products */, 95 | ); 96 | sourceTree = ""; 97 | }; 98 | 456E8C9218D93EEE00C5AC4A /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 456E8C9118D93EEE00C5AC4A /* PreviewImageViewDemo.app */, 102 | 456E8CB218D93EEE00C5AC4A /* PreviewImageViewDemoTests.xctest */, 103 | ); 104 | name = Products; 105 | sourceTree = ""; 106 | }; 107 | 456E8C9318D93EEE00C5AC4A /* Frameworks */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 456E8C9418D93EEE00C5AC4A /* Foundation.framework */, 111 | 456E8C9618D93EEE00C5AC4A /* CoreGraphics.framework */, 112 | 456E8C9818D93EEE00C5AC4A /* UIKit.framework */, 113 | 456E8CB318D93EEE00C5AC4A /* XCTest.framework */, 114 | ); 115 | name = Frameworks; 116 | sourceTree = ""; 117 | }; 118 | 456E8C9A18D93EEE00C5AC4A /* PreviewImageViewDemo */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 456E8CA318D93EEE00C5AC4A /* AppDelegate.h */, 122 | 456E8CA418D93EEE00C5AC4A /* AppDelegate.m */, 123 | 456E8CA618D93EEE00C5AC4A /* Main.storyboard */, 124 | 456E8CA918D93EEE00C5AC4A /* ViewController.h */, 125 | 456E8CAA18D93EEE00C5AC4A /* ViewController.m */, 126 | 456E8CAC18D93EEE00C5AC4A /* Images.xcassets */, 127 | 45A3A72E18D944FC002A17F4 /* test.png */, 128 | 456E8C9B18D93EEE00C5AC4A /* Supporting Files */, 129 | ); 130 | path = PreviewImageViewDemo; 131 | sourceTree = ""; 132 | }; 133 | 456E8C9B18D93EEE00C5AC4A /* Supporting Files */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 456E8C9C18D93EEE00C5AC4A /* PreviewImageViewDemo-Info.plist */, 137 | 456E8C9D18D93EEE00C5AC4A /* InfoPlist.strings */, 138 | 456E8CA018D93EEE00C5AC4A /* main.m */, 139 | 456E8CA218D93EEE00C5AC4A /* PreviewImageViewDemo-Prefix.pch */, 140 | ); 141 | name = "Supporting Files"; 142 | sourceTree = ""; 143 | }; 144 | 456E8CB918D93EEE00C5AC4A /* PreviewImageViewDemoTests */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 456E8CBF18D93EEE00C5AC4A /* PreviewImageViewDemoTests.m */, 148 | 456E8CBA18D93EEE00C5AC4A /* Supporting Files */, 149 | ); 150 | path = PreviewImageViewDemoTests; 151 | sourceTree = ""; 152 | }; 153 | 456E8CBA18D93EEE00C5AC4A /* Supporting Files */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 456E8CBB18D93EEE00C5AC4A /* PreviewImageViewDemoTests-Info.plist */, 157 | 456E8CBC18D93EEE00C5AC4A /* InfoPlist.strings */, 158 | ); 159 | name = "Supporting Files"; 160 | sourceTree = ""; 161 | }; 162 | 456E8CC918D93F2800C5AC4A /* PreviewImageView */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 456E8CCA18D93F3D00C5AC4A /* PreviewImageView.h */, 166 | 456E8CCB18D93F3D00C5AC4A /* PreviewImageView.m */, 167 | ); 168 | name = PreviewImageView; 169 | sourceTree = ""; 170 | }; 171 | /* End PBXGroup section */ 172 | 173 | /* Begin PBXNativeTarget section */ 174 | 456E8C9018D93EEE00C5AC4A /* PreviewImageViewDemo */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = 456E8CC318D93EEE00C5AC4A /* Build configuration list for PBXNativeTarget "PreviewImageViewDemo" */; 177 | buildPhases = ( 178 | 456E8C8D18D93EEE00C5AC4A /* Sources */, 179 | 456E8C8E18D93EEE00C5AC4A /* Frameworks */, 180 | 456E8C8F18D93EEE00C5AC4A /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | ); 186 | name = PreviewImageViewDemo; 187 | productName = PreviewImageViewDemo; 188 | productReference = 456E8C9118D93EEE00C5AC4A /* PreviewImageViewDemo.app */; 189 | productType = "com.apple.product-type.application"; 190 | }; 191 | 456E8CB118D93EEE00C5AC4A /* PreviewImageViewDemoTests */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 456E8CC618D93EEE00C5AC4A /* Build configuration list for PBXNativeTarget "PreviewImageViewDemoTests" */; 194 | buildPhases = ( 195 | 456E8CAE18D93EEE00C5AC4A /* Sources */, 196 | 456E8CAF18D93EEE00C5AC4A /* Frameworks */, 197 | 456E8CB018D93EEE00C5AC4A /* Resources */, 198 | ); 199 | buildRules = ( 200 | ); 201 | dependencies = ( 202 | 456E8CB818D93EEE00C5AC4A /* PBXTargetDependency */, 203 | ); 204 | name = PreviewImageViewDemoTests; 205 | productName = PreviewImageViewDemoTests; 206 | productReference = 456E8CB218D93EEE00C5AC4A /* PreviewImageViewDemoTests.xctest */; 207 | productType = "com.apple.product-type.bundle.unit-test"; 208 | }; 209 | /* End PBXNativeTarget section */ 210 | 211 | /* Begin PBXProject section */ 212 | 456E8C8918D93EEE00C5AC4A /* Project object */ = { 213 | isa = PBXProject; 214 | attributes = { 215 | LastUpgradeCheck = 0500; 216 | ORGANIZATIONNAME = kingzwt; 217 | TargetAttributes = { 218 | 456E8CB118D93EEE00C5AC4A = { 219 | TestTargetID = 456E8C9018D93EEE00C5AC4A; 220 | }; 221 | }; 222 | }; 223 | buildConfigurationList = 456E8C8C18D93EEE00C5AC4A /* Build configuration list for PBXProject "PreviewImageViewDemo" */; 224 | compatibilityVersion = "Xcode 3.2"; 225 | developmentRegion = English; 226 | hasScannedForEncodings = 0; 227 | knownRegions = ( 228 | en, 229 | Base, 230 | ); 231 | mainGroup = 456E8C8818D93EEE00C5AC4A; 232 | productRefGroup = 456E8C9218D93EEE00C5AC4A /* Products */; 233 | projectDirPath = ""; 234 | projectRoot = ""; 235 | targets = ( 236 | 456E8C9018D93EEE00C5AC4A /* PreviewImageViewDemo */, 237 | 456E8CB118D93EEE00C5AC4A /* PreviewImageViewDemoTests */, 238 | ); 239 | }; 240 | /* End PBXProject section */ 241 | 242 | /* Begin PBXResourcesBuildPhase section */ 243 | 456E8C8F18D93EEE00C5AC4A /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 456E8CAD18D93EEE00C5AC4A /* Images.xcassets in Resources */, 248 | 456E8C9F18D93EEE00C5AC4A /* InfoPlist.strings in Resources */, 249 | 456E8CA818D93EEE00C5AC4A /* Main.storyboard in Resources */, 250 | 45A3A72F18D944FC002A17F4 /* test.png in Resources */, 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | 456E8CB018D93EEE00C5AC4A /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | 456E8CBE18D93EEE00C5AC4A /* InfoPlist.strings in Resources */, 259 | ); 260 | runOnlyForDeploymentPostprocessing = 0; 261 | }; 262 | /* End PBXResourcesBuildPhase section */ 263 | 264 | /* Begin PBXSourcesBuildPhase section */ 265 | 456E8C8D18D93EEE00C5AC4A /* Sources */ = { 266 | isa = PBXSourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | 456E8CCC18D93F3D00C5AC4A /* PreviewImageView.m in Sources */, 270 | 456E8CAB18D93EEE00C5AC4A /* ViewController.m in Sources */, 271 | 456E8CA518D93EEE00C5AC4A /* AppDelegate.m in Sources */, 272 | 456E8CA118D93EEE00C5AC4A /* main.m in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | 456E8CAE18D93EEE00C5AC4A /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 456E8CC018D93EEE00C5AC4A /* PreviewImageViewDemoTests.m in Sources */, 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | }; 284 | /* End PBXSourcesBuildPhase section */ 285 | 286 | /* Begin PBXTargetDependency section */ 287 | 456E8CB818D93EEE00C5AC4A /* PBXTargetDependency */ = { 288 | isa = PBXTargetDependency; 289 | target = 456E8C9018D93EEE00C5AC4A /* PreviewImageViewDemo */; 290 | targetProxy = 456E8CB718D93EEE00C5AC4A /* PBXContainerItemProxy */; 291 | }; 292 | /* End PBXTargetDependency section */ 293 | 294 | /* Begin PBXVariantGroup section */ 295 | 456E8C9D18D93EEE00C5AC4A /* InfoPlist.strings */ = { 296 | isa = PBXVariantGroup; 297 | children = ( 298 | 456E8C9E18D93EEE00C5AC4A /* en */, 299 | ); 300 | name = InfoPlist.strings; 301 | sourceTree = ""; 302 | }; 303 | 456E8CA618D93EEE00C5AC4A /* Main.storyboard */ = { 304 | isa = PBXVariantGroup; 305 | children = ( 306 | 456E8CA718D93EEE00C5AC4A /* Base */, 307 | ); 308 | name = Main.storyboard; 309 | sourceTree = ""; 310 | }; 311 | 456E8CBC18D93EEE00C5AC4A /* InfoPlist.strings */ = { 312 | isa = PBXVariantGroup; 313 | children = ( 314 | 456E8CBD18D93EEE00C5AC4A /* en */, 315 | ); 316 | name = InfoPlist.strings; 317 | sourceTree = ""; 318 | }; 319 | /* End PBXVariantGroup section */ 320 | 321 | /* Begin XCBuildConfiguration section */ 322 | 456E8CC118D93EEE00C5AC4A /* Debug */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | ALWAYS_SEARCH_USER_PATHS = NO; 326 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 327 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 328 | CLANG_CXX_LIBRARY = "libc++"; 329 | CLANG_ENABLE_MODULES = YES; 330 | CLANG_ENABLE_OBJC_ARC = YES; 331 | CLANG_WARN_BOOL_CONVERSION = YES; 332 | CLANG_WARN_CONSTANT_CONVERSION = YES; 333 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 334 | CLANG_WARN_EMPTY_BODY = YES; 335 | CLANG_WARN_ENUM_CONVERSION = YES; 336 | CLANG_WARN_INT_CONVERSION = YES; 337 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 338 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 339 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 340 | COPY_PHASE_STRIP = NO; 341 | GCC_C_LANGUAGE_STANDARD = gnu99; 342 | GCC_DYNAMIC_NO_PIC = NO; 343 | GCC_OPTIMIZATION_LEVEL = 0; 344 | GCC_PREPROCESSOR_DEFINITIONS = ( 345 | "DEBUG=1", 346 | "$(inherited)", 347 | ); 348 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 349 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 350 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 351 | GCC_WARN_UNDECLARED_SELECTOR = YES; 352 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 353 | GCC_WARN_UNUSED_FUNCTION = YES; 354 | GCC_WARN_UNUSED_VARIABLE = YES; 355 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 356 | ONLY_ACTIVE_ARCH = YES; 357 | SDKROOT = iphoneos; 358 | }; 359 | name = Debug; 360 | }; 361 | 456E8CC218D93EEE00C5AC4A /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ALWAYS_SEARCH_USER_PATHS = NO; 365 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 366 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 367 | CLANG_CXX_LIBRARY = "libc++"; 368 | CLANG_ENABLE_MODULES = YES; 369 | CLANG_ENABLE_OBJC_ARC = YES; 370 | CLANG_WARN_BOOL_CONVERSION = YES; 371 | CLANG_WARN_CONSTANT_CONVERSION = YES; 372 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 373 | CLANG_WARN_EMPTY_BODY = YES; 374 | CLANG_WARN_ENUM_CONVERSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 377 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 378 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 379 | COPY_PHASE_STRIP = YES; 380 | ENABLE_NS_ASSERTIONS = NO; 381 | GCC_C_LANGUAGE_STANDARD = gnu99; 382 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 383 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 384 | GCC_WARN_UNDECLARED_SELECTOR = YES; 385 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 386 | GCC_WARN_UNUSED_FUNCTION = YES; 387 | GCC_WARN_UNUSED_VARIABLE = YES; 388 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 389 | SDKROOT = iphoneos; 390 | VALIDATE_PRODUCT = YES; 391 | }; 392 | name = Release; 393 | }; 394 | 456E8CC418D93EEE00C5AC4A /* Debug */ = { 395 | isa = XCBuildConfiguration; 396 | buildSettings = { 397 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 398 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 399 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 400 | GCC_PREFIX_HEADER = "PreviewImageViewDemo/PreviewImageViewDemo-Prefix.pch"; 401 | INFOPLIST_FILE = "PreviewImageViewDemo/PreviewImageViewDemo-Info.plist"; 402 | PRODUCT_NAME = "$(TARGET_NAME)"; 403 | WRAPPER_EXTENSION = app; 404 | }; 405 | name = Debug; 406 | }; 407 | 456E8CC518D93EEE00C5AC4A /* Release */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 411 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 412 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 413 | GCC_PREFIX_HEADER = "PreviewImageViewDemo/PreviewImageViewDemo-Prefix.pch"; 414 | INFOPLIST_FILE = "PreviewImageViewDemo/PreviewImageViewDemo-Info.plist"; 415 | PRODUCT_NAME = "$(TARGET_NAME)"; 416 | WRAPPER_EXTENSION = app; 417 | }; 418 | name = Release; 419 | }; 420 | 456E8CC718D93EEE00C5AC4A /* Debug */ = { 421 | isa = XCBuildConfiguration; 422 | buildSettings = { 423 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 424 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/PreviewImageViewDemo.app/PreviewImageViewDemo"; 425 | FRAMEWORK_SEARCH_PATHS = ( 426 | "$(SDKROOT)/Developer/Library/Frameworks", 427 | "$(inherited)", 428 | "$(DEVELOPER_FRAMEWORKS_DIR)", 429 | ); 430 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 431 | GCC_PREFIX_HEADER = "PreviewImageViewDemo/PreviewImageViewDemo-Prefix.pch"; 432 | GCC_PREPROCESSOR_DEFINITIONS = ( 433 | "DEBUG=1", 434 | "$(inherited)", 435 | ); 436 | INFOPLIST_FILE = "PreviewImageViewDemoTests/PreviewImageViewDemoTests-Info.plist"; 437 | PRODUCT_NAME = "$(TARGET_NAME)"; 438 | TEST_HOST = "$(BUNDLE_LOADER)"; 439 | WRAPPER_EXTENSION = xctest; 440 | }; 441 | name = Debug; 442 | }; 443 | 456E8CC818D93EEE00C5AC4A /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | buildSettings = { 446 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; 447 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/PreviewImageViewDemo.app/PreviewImageViewDemo"; 448 | FRAMEWORK_SEARCH_PATHS = ( 449 | "$(SDKROOT)/Developer/Library/Frameworks", 450 | "$(inherited)", 451 | "$(DEVELOPER_FRAMEWORKS_DIR)", 452 | ); 453 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 454 | GCC_PREFIX_HEADER = "PreviewImageViewDemo/PreviewImageViewDemo-Prefix.pch"; 455 | INFOPLIST_FILE = "PreviewImageViewDemoTests/PreviewImageViewDemoTests-Info.plist"; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | TEST_HOST = "$(BUNDLE_LOADER)"; 458 | WRAPPER_EXTENSION = xctest; 459 | }; 460 | name = Release; 461 | }; 462 | /* End XCBuildConfiguration section */ 463 | 464 | /* Begin XCConfigurationList section */ 465 | 456E8C8C18D93EEE00C5AC4A /* Build configuration list for PBXProject "PreviewImageViewDemo" */ = { 466 | isa = XCConfigurationList; 467 | buildConfigurations = ( 468 | 456E8CC118D93EEE00C5AC4A /* Debug */, 469 | 456E8CC218D93EEE00C5AC4A /* Release */, 470 | ); 471 | defaultConfigurationIsVisible = 0; 472 | defaultConfigurationName = Release; 473 | }; 474 | 456E8CC318D93EEE00C5AC4A /* Build configuration list for PBXNativeTarget "PreviewImageViewDemo" */ = { 475 | isa = XCConfigurationList; 476 | buildConfigurations = ( 477 | 456E8CC418D93EEE00C5AC4A /* Debug */, 478 | 456E8CC518D93EEE00C5AC4A /* Release */, 479 | ); 480 | defaultConfigurationIsVisible = 0; 481 | defaultConfigurationName = Release; 482 | }; 483 | 456E8CC618D93EEE00C5AC4A /* Build configuration list for PBXNativeTarget "PreviewImageViewDemoTests" */ = { 484 | isa = XCConfigurationList; 485 | buildConfigurations = ( 486 | 456E8CC718D93EEE00C5AC4A /* Debug */, 487 | 456E8CC818D93EEE00C5AC4A /* Release */, 488 | ); 489 | defaultConfigurationIsVisible = 0; 490 | defaultConfigurationName = Release; 491 | }; 492 | /* End XCConfigurationList section */ 493 | }; 494 | rootObject = 456E8C8918D93EEE00C5AC4A /* Project object */; 495 | } 496 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo.xcodeproj/project.xcworkspace/xcuserdata/kingzwt.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joywii/PreviewImageView/fe75802b184655a91602119e4109bbe3512ea460/PreviewImageViewDemo/PreviewImageViewDemo.xcodeproj/project.xcworkspace/xcuserdata/kingzwt.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo.xcodeproj/xcuserdata/kingzwt.xcuserdatad/xcschemes/PreviewImageViewDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PreviewImageViewDemo 4 | // 5 | // Created by Joywii on 14-3-19. 6 | // Copyright (c) 2014年 Joywii. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PreviewImageViewDemo 4 | // 5 | // Created by Joywii on 14-3-19. 6 | // Copyright (c) 2014年 Joywii. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/PreviewImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewPhotoView.h 3 | // 4 | // 5 | // Created by Joywii on 13-10-16. 6 | // Copyright (c) 2013年 Joywii. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PreviewImageView : UIView 12 | 13 | + (void)showPreviewImage:(UIImage *)image startImageFrame:(CGRect)startImageFrame inView:(UIView *)inView viewFrame:(CGRect)viewFrame; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/PreviewImageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewPhotoView.m 3 | // 4 | // 5 | // Created by Joywii on 13-10-16. 6 | // Copyright (c) 2013年 Joywii. All rights reserved. 7 | // 8 | 9 | #import "PreviewImageView.h" 10 | #import 11 | #import 12 | 13 | @interface PreviewImageView () 14 | 15 | @property (nonatomic,strong) UIView *contentView; 16 | @property (nonatomic,strong) UIImageView *photoImageView; 17 | @property (nonatomic,strong) NSValue *starRectValue; 18 | @property (nonatomic,strong) NSValue *imageRectValue; 19 | 20 | @end 21 | 22 | @implementation PreviewImageView 23 | 24 | + (void)showPreviewImage:(UIImage *)image startImageFrame:(CGRect)startImageFrame inView:(UIView *)inView viewFrame:(CGRect)viewFrame 25 | { 26 | PreviewImageView *preImageView = [[PreviewImageView alloc] initWithFrame:viewFrame withImage:image startFrame:startImageFrame]; 27 | [inView addSubview:preImageView]; 28 | } 29 | - (id)initWithFrame:(CGRect)frame withImage:(UIImage *)image startFrame:(CGRect)startFrame 30 | { 31 | self = [super initWithFrame:frame]; 32 | if (self) 33 | { 34 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 35 | self.opaque = YES; 36 | 37 | self.starRectValue = [NSValue valueWithCGRect:startFrame]; 38 | 39 | self.contentView = [[UIView alloc] initWithFrame:startFrame]; 40 | self.contentView.backgroundColor = [UIColor clearColor]; 41 | self.contentView.userInteractionEnabled = YES; 42 | self.contentView.clipsToBounds = YES; 43 | self.contentView.layer.masksToBounds = YES; 44 | self.contentView.layer.cornerRadius = 3.0; 45 | [self addSubview:self.contentView]; 46 | 47 | CGRect imageFrame = startFrame; 48 | imageFrame.origin.x = 0; 49 | imageFrame.origin.y = 0; 50 | self.imageRectValue = [NSValue valueWithCGRect:imageFrame]; 51 | 52 | self.photoImageView = [[UIImageView alloc] initWithFrame:imageFrame]; 53 | self.photoImageView.contentMode = UIViewContentModeScaleAspectFit; 54 | self.photoImageView.image = image; 55 | self.photoImageView.backgroundColor = [UIColor clearColor]; 56 | self.photoImageView.userInteractionEnabled = YES; 57 | [self.contentView addSubview:self.photoImageView]; 58 | 59 | [self addTapPressGestureRecognizer]; 60 | [self addLongPressGestureRecognizer]; 61 | 62 | [UIView beginAnimations:@"backgroundcolor" context:nil]; 63 | [UIView setAnimationDuration:0.1]; 64 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 65 | self.backgroundColor = [UIColor blackColor]; 66 | [UIView commitAnimations]; 67 | 68 | [self startShowAnimation]; 69 | } 70 | return self; 71 | } 72 | - (void)handleTapView:(UIGestureRecognizer *)gestureRecognizer 73 | { 74 | [self startHideAnimation]; 75 | [self performSelector:@selector(hide) withObject:nil afterDelay:0.4]; 76 | } 77 | - (void)hide 78 | { 79 | [self removeFromSuperview]; 80 | } 81 | - (void)startShowAnimation 82 | { 83 | [UIView beginAnimations:@"scaleImageShow" context:nil]; 84 | [UIView setAnimationDelegate:self]; 85 | [UIView setAnimationDuration:0.4]; 86 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 87 | self.photoImageView.frame = self.bounds; 88 | self.contentView.frame = self.bounds; 89 | [UIView commitAnimations]; 90 | } 91 | - (void)startHideAnimation 92 | { 93 | [UIView beginAnimations:@"scaleImageHide" context:nil]; 94 | [UIView setAnimationDelegate:self]; 95 | [UIView setAnimationDuration:0.4]; 96 | [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; 97 | self.photoImageView.frame = [self.imageRectValue CGRectValue]; 98 | self.contentView.frame = [self.starRectValue CGRectValue]; 99 | self.backgroundColor = [UIColor clearColor]; 100 | [UIView commitAnimations]; 101 | } 102 | - (void)addTapPressGestureRecognizer 103 | { 104 | UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] init]; 105 | 106 | tapGR.cancelsTouchesInView = NO; 107 | tapGR.delaysTouchesBegan = NO; 108 | tapGR.delaysTouchesEnded = NO; 109 | tapGR.numberOfTapsRequired = 1; 110 | tapGR.numberOfTouchesRequired = 1; 111 | 112 | [tapGR addTarget:self action:@selector(handleTapView:)]; 113 | [self addGestureRecognizer:tapGR]; 114 | } 115 | - (void)addLongPressGestureRecognizer 116 | { 117 | UILongPressGestureRecognizer *longPressGR = 118 | [[UILongPressGestureRecognizer alloc] initWithTarget:self 119 | action:@selector(handleLongPress:)]; 120 | 121 | [longPressGR setMinimumPressDuration:0.4]; 122 | [self addGestureRecognizer:longPressGR]; 123 | } 124 | 125 | - (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer 126 | { 127 | if (gestureRecognizer.state == UIGestureRecognizerStateBegan) 128 | { 129 | UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:nil 130 | delegate:self 131 | cancelButtonTitle:@"取消" 132 | destructiveButtonTitle:@"保存到相册" 133 | otherButtonTitles:nil]; 134 | action.actionSheetStyle = UIActionSheetStyleDefault; 135 | action.tag = 123456; 136 | 137 | [action showInView:self]; 138 | } 139 | } 140 | #pragma mark - UIActionSheetDelegate 141 | - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 142 | { 143 | if(actionSheet.tag == 123456 && buttonIndex == 0) 144 | { 145 | if (self.photoImageView.image) 146 | { 147 | UIImageWriteToSavedPhotosAlbum(self.photoImageView.image,self,@selector(image:didFinishSavingWithError:contextInfo:),nil); 148 | } 149 | else 150 | { 151 | NSLog(@"image is nil"); 152 | } 153 | } 154 | } 155 | -(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo 156 | { 157 | if (error != NULL) 158 | { 159 | NSLog(@"%@",error); 160 | } 161 | else 162 | { 163 | NSLog(@"save success!"); 164 | } 165 | } 166 | @end 167 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/PreviewImageViewDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | sohu.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/PreviewImageViewDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PreviewImageViewDemo 4 | // 5 | // Created by Joywii on 14-3-19. 6 | // Copyright (c) 2014年 Joywii. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PreviewImageViewDemo 4 | // 5 | // Created by Joywii on 14-3-19. 6 | // Copyright (c) 2014年 Joywii. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "PreviewImageView.h" 11 | 12 | 13 | @interface ViewController () 14 | 15 | @property (nonatomic,strong) UIImageView *imageView; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad 22 | { 23 | [super viewDidLoad]; 24 | // Do any additional setup after loading the view, typically from a nib. 25 | 26 | self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(125, 200, 70, 100)]; 27 | self.imageView.image = [UIImage imageNamed:@"test"]; 28 | self.imageView.contentMode = UIViewContentModeScaleAspectFill; 29 | self.imageView.layer.masksToBounds = YES; 30 | self.imageView.layer.cornerRadius = 3.0; 31 | self.imageView.userInteractionEnabled = YES; 32 | [self.view addSubview:self.imageView]; 33 | 34 | UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] init]; 35 | tapGR.cancelsTouchesInView = YES; 36 | tapGR.delaysTouchesBegan = NO; 37 | tapGR.delaysTouchesEnded = NO; 38 | tapGR.numberOfTapsRequired = 1; 39 | tapGR.numberOfTouchesRequired = 1; 40 | [tapGR addTarget:self action:@selector(handleTapView:)]; 41 | [self.imageView addGestureRecognizer:tapGR]; 42 | } 43 | 44 | - (void)didReceiveMemoryWarning 45 | { 46 | [super didReceiveMemoryWarning]; 47 | // Dispose of any resources that can be recreated. 48 | } 49 | - (void)handleTapView:(UIGestureRecognizer *)gestureRecognizer 50 | { 51 | UIWindow *windows = [UIApplication sharedApplication].keyWindow; 52 | CGRect startRect = [self.imageView convertRect:self.imageView.bounds toView:windows]; 53 | [PreviewImageView showPreviewImage:self.imageView.image startImageFrame:startRect inView:windows viewFrame:self.view.bounds]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PreviewImageViewDemo 4 | // 5 | // Created by Joywii on 14-3-19. 6 | // Copyright (c) 2014年 Joywii. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemo/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Joywii/PreviewImageView/fe75802b184655a91602119e4109bbe3512ea460/PreviewImageViewDemo/PreviewImageViewDemo/test.png -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemoTests/PreviewImageViewDemoTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | sohu.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemoTests/PreviewImageViewDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // PreviewImageViewDemoTests.m 3 | // PreviewImageViewDemoTests 4 | // 5 | // Created by Joywii on 14-3-19. 6 | // Copyright (c) 2014年 Joywii. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PreviewImageViewDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation PreviewImageViewDemoTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /PreviewImageViewDemo/PreviewImageViewDemoTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PreviewImageView 2 | ================ 3 | 4 | 图片从小图到全屏大图的预览和长按保存到本地相册(类似很多社交类应用图片预览的实现) 5 | 6 | ###如何使用 7 | ``` 8 | UIWindow *windows = [UIApplication sharedApplication].keyWindow; 9 | CGRect startRect = [self.imageView convertRect:self.imageView.bounds toView:windows]; 10 | [PreviewImageView showPreviewImage:self.imageView.image startImageFrame:startRect inView:windows viewFrame:self.view.bounds];) 11 | ``` 12 | --------------------------------------------------------------------------------