├── .gitignore ├── README.md ├── RoundButton.h ├── RoundButton.m ├── ZoomImageView.h ├── ZoomImageView.m └── 如何使用 /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZoomImage 2 | 圆形图片,点击放大,然后再点击缩小到圆形图片位置 3 | -------------------------------------------------------------------------------- /RoundButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // RoundButton.h 3 | // zoomImage 4 | // 5 | // Created by Mapollo27 on 15/6/3. 6 | // Copyright (c) 2015年 Mapollo27. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | #pragma mark - ZoomImageCache interface 14 | 15 | @interface ZoomImageCache : NSObject 16 | 17 | @property (nonatomic, strong) NSString *cachePath; 18 | @property (nonatomic, strong) NSFileManager *fileManager; 19 | 20 | - (void)setImage:(UIImage *)image forURL:(NSString *)URL; 21 | - (UIImage *)getImageForURL:(NSString *)URL; 22 | 23 | @end 24 | 25 | 26 | @interface RoundButton : UIButton 27 | { 28 | UIColor *rippleColor; 29 | } 30 | @property (nonatomic, assign, getter = isCacheEnabled) BOOL cacheEnabled; 31 | @property (nonatomic, strong) CAShapeLayer *backgroundLayer; 32 | @property (nonatomic, strong) CAShapeLayer *progressLayer; 33 | @property (nonatomic, strong) UIImageView *containerImageView; 34 | @property (nonatomic, strong) UIView *progressContainer; 35 | @property (nonatomic, strong) ZoomImageCache *cache; 36 | 37 | 38 | - (id)initWithFrame:(CGRect)frame backgroundProgressColor:(UIColor *)backgroundProgresscolor progressColor:(UIColor *)progressColor; 39 | - (void)setImageURL:(NSString *)URL imageFrame:(CGRect)frame; 40 | 41 | @end 42 | 43 | -------------------------------------------------------------------------------- /RoundButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // RoundButton.m 3 | // zoomImage 4 | // 5 | // Created by Mapollo27 on 15/6/3. 6 | // Copyright (c) 2015年 Mapollo27. All rights reserved. 7 | // 8 | 9 | #import "RoundButton.h" 10 | #import "AFNetworking.h" 11 | 12 | #define rad(degrees) ((degrees) / (180.0 / M_PI)) 13 | #define kLineWidth 3.f 14 | 15 | 16 | @implementation RoundButton 17 | 18 | - (id)initWithFrame:(CGRect)frame { 19 | return [[RoundButton alloc] initWithFrame:frame 20 | backgroundProgressColor:[UIColor whiteColor] 21 | progressColor:[UIColor colorWithRed:240/255.f green:85/255.f blue:97/255.f alpha:1.f]]; 22 | } 23 | 24 | 25 | 26 | - (id)initWithFrame:(CGRect)frame backgroundProgressColor:(UIColor *)backgroundProgresscolor progressColor:(UIColor *)progressColor 27 | { 28 | self = [super initWithFrame:frame]; 29 | if (self) 30 | { 31 | self.layer.cornerRadius = CGRectGetWidth(self.bounds)/2.f; 32 | self.layer.masksToBounds = NO; 33 | self.clipsToBounds = YES; 34 | _cacheEnabled = YES; 35 | self.layer.borderWidth = 1; 36 | self.layer.borderColor = [UIColor grayColor].CGColor; 37 | 38 | CGPoint arcCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); 39 | CGFloat radius = MIN(CGRectGetMidX(self.bounds)-1, CGRectGetMidY(self.bounds)-1); 40 | 41 | UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:arcCenter 42 | radius:radius 43 | startAngle:-rad(90) 44 | endAngle:rad(360-90) 45 | clockwise:YES]; 46 | 47 | _backgroundLayer = [CAShapeLayer layer]; 48 | _backgroundLayer.path = circlePath.CGPath; 49 | _backgroundLayer.strokeColor = [backgroundProgresscolor CGColor]; 50 | _backgroundLayer.fillColor = [[UIColor clearColor] CGColor]; 51 | _backgroundLayer.lineWidth = kLineWidth; 52 | 53 | 54 | _progressLayer = [CAShapeLayer layer]; 55 | _progressLayer.path = _backgroundLayer.path; 56 | _progressLayer.strokeColor = [progressColor CGColor]; 57 | _progressLayer.fillColor = _backgroundLayer.fillColor; 58 | _progressLayer.lineWidth = _backgroundLayer.lineWidth; 59 | _progressLayer.strokeEnd = 0.f; 60 | 61 | _progressContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; 62 | _progressContainer.layer.cornerRadius = CGRectGetWidth(self.bounds)/2.f; 63 | _progressContainer.layer.masksToBounds = NO; 64 | _progressContainer.clipsToBounds = YES; 65 | _progressContainer.backgroundColor = [UIColor clearColor]; 66 | 67 | _containerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(1, 1, frame.size.width-2, frame.size.height-2)]; 68 | _containerImageView.layer.cornerRadius = CGRectGetWidth(self.bounds)/2.f; 69 | _containerImageView.layer.masksToBounds = NO; 70 | _containerImageView.clipsToBounds = YES; 71 | _containerImageView.contentMode = UIViewContentModeScaleAspectFill; 72 | 73 | [_progressContainer.layer addSublayer:_backgroundLayer]; 74 | [_progressContainer.layer addSublayer:_progressLayer]; 75 | 76 | [self addSubview:_containerImageView]; 77 | [self addSubview:_progressContainer]; 78 | } 79 | return self; 80 | } 81 | 82 | - (void)setImageURL:(NSString *)URL imageFrame:(CGRect)frame 83 | { 84 | NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]]; 85 | UIImage *cachedImage = (_cacheEnabled) ? [_cache getImageForURL:URL] : nil; 86 | if(cachedImage) 87 | { 88 | [self updateWithImage:cachedImage animated:NO]; 89 | } else { 90 | __weak __typeof(self)weakSelf = self; 91 | AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest]; 92 | requestOperation.responseSerializer = [AFImageResponseSerializer serializer]; 93 | 94 | [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) 95 | { 96 | UIImage *image = responseObject; 97 | [weakSelf updateWithImage:image animated:YES]; 98 | if(_cacheEnabled) 99 | { 100 | [_cache setImage:responseObject forURL:URL]; 101 | } 102 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) 103 | { 104 | NSLog(@"Image error: %@", error); 105 | }]; 106 | [requestOperation start]; 107 | } 108 | } 109 | 110 | //加载网络图片并添加动画 111 | - (void)updateWithImage:(UIImage *)image animated:(BOOL)animated 112 | { 113 | CGFloat duration = (animated) ? 0.2 : 0.f; 114 | CGFloat delay = (animated) ? 0.1 : 0.f; 115 | _containerImageView.transform = CGAffineTransformMakeScale(0, 0); 116 | _containerImageView.alpha = 0.f; 117 | _containerImageView.image = image; 118 | [UIView animateWithDuration:duration animations:^{ 119 | _progressContainer.transform = CGAffineTransformMakeScale(1.1, 1.1); 120 | _progressContainer.alpha = 0.f; 121 | [UIView animateWithDuration:duration 122 | delay:delay 123 | options:UIViewAnimationOptionCurveEaseOut 124 | animations:^{ 125 | _containerImageView.transform = CGAffineTransformIdentity; 126 | _containerImageView.alpha = 1.f; 127 | } completion:nil]; 128 | } completion:^(BOOL finished) { 129 | _progressLayer.strokeColor = [[UIColor whiteColor] CGColor]; 130 | [UIView animateWithDuration:duration 131 | animations:^{ 132 | _progressContainer.transform = CGAffineTransformIdentity; 133 | _progressContainer.alpha = 1.f; 134 | }]; 135 | }]; 136 | } 137 | 138 | 139 | @end 140 | 141 | #pragma mark - ZoomImageCache 142 | 143 | @implementation ZoomImageCache 144 | 145 | - (instancetype)init 146 | { 147 | self = [super init]; 148 | if(self) 149 | { 150 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 151 | NSString *rootCachePath = [paths firstObject]; 152 | 153 | _fileManager = [NSFileManager defaultManager]; 154 | _cachePath = [rootCachePath stringByAppendingPathComponent:@"zoom.imagecache.tg"]; 155 | 156 | if(![_fileManager fileExistsAtPath:@"zoom.imagecache.tg"]) 157 | { 158 | [_fileManager createDirectoryAtPath:_cachePath withIntermediateDirectories:NO attributes:nil error:nil]; 159 | } 160 | } 161 | return self; 162 | } 163 | 164 | - (void)setImage:(UIImage *)image forURL:(NSString *)URL 165 | { 166 | NSData *imageData = nil; 167 | NSString *fileExtension = [[URL componentsSeparatedByString:@"."] lastObject]; 168 | if([fileExtension isEqualToString:@"png"]) 169 | { 170 | imageData = UIImagePNGRepresentation(image); 171 | } 172 | else if([fileExtension isEqualToString:@"jpg"] || [fileExtension isEqualToString:@"jpeg"]) 173 | { 174 | imageData = UIImageJPEGRepresentation(image, 1.f); 175 | } 176 | else return; 177 | 178 | [imageData writeToFile:[_cachePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%lu.%@", (unsigned long)URL.hash, fileExtension]] atomically:YES]; 179 | } 180 | 181 | - (UIImage *)getImageForURL:(NSString *)URL 182 | { 183 | NSString *fileExtension = [[URL componentsSeparatedByString:@"."] lastObject]; 184 | NSString *path = [_cachePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%lu.%@", (unsigned long)URL.hash, fileExtension]]; 185 | if([_fileManager fileExistsAtPath:path]) 186 | { 187 | return [UIImage imageWithData:[NSData dataWithContentsOfFile:path]]; 188 | } 189 | return nil; 190 | } 191 | 192 | 193 | @end 194 | -------------------------------------------------------------------------------- /ZoomImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomImageView 3 | // zoomImage 4 | // 5 | // Created by Mapollo27 on 15/6/3. 6 | // Copyright (c) 2015年 Mapollo27. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RoundButton.h" 11 | 12 | @interface ZoomImageView : UIView 13 | { 14 | RoundButton* topButton[20]; 15 | int buttonIndex; 16 | NSMutableArray *imageArray; 17 | float roundButtonPosY; 18 | float roundButtonPosX; 19 | } 20 | 21 | //最底层view 22 | @property (nonatomic ,strong) UIView *backgroundViewDown; 23 | //最大图片 24 | @property (nonatomic ,strong) UIImageView *imageViewBig; 25 | //按钮 26 | @property (nonatomic ,strong) RoundButton *roundButton; 27 | @property (nonatomic ,strong) UIWindow *window; 28 | @property (nonatomic ,strong) UIImageView *imageViewZoom; 29 | @property (nonatomic ,strong) UIView *backgViewTop; 30 | 31 | - (id)initWithFrame:(CGRect)frame; 32 | -(void) setImageArray:(NSMutableArray*) array artId:(NSString *)ID; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /ZoomImageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomImageView 3 | // zoomImage 4 | // 5 | // Created by Mapollo27 on 15/6/3. 6 | // Copyright (c) 2015年 Mapollo27. All rights reserved. 7 | // 8 | 9 | #import "ZoomImageView.h" 10 | 11 | #define deyTime 0.45f //图片动画持续时间 12 | #define roundBtnWH 40 13 | 14 | static CGRect oldframe; 15 | 16 | @implementation ZoomImageView 17 | @synthesize backgroundViewDown; 18 | @synthesize imageViewBig; 19 | @synthesize roundButton; 20 | @synthesize imageViewZoom; 21 | @synthesize backgViewTop; 22 | 23 | //初始化图片控件 24 | - (id)initWithFrame:(CGRect)frame 25 | { 26 | self = [super initWithFrame:frame]; 27 | if (self) 28 | { 29 | roundButtonPosY = frame.size.height-roundBtnWH-10; 30 | roundButtonPosX =frame.size.width-roundBtnWH-10; 31 | 32 | buttonIndex = 1; 33 | backgroundViewDown = [[UIView alloc ] initWithFrame:frame]; 34 | [backgroundViewDown setBackgroundColor:[UIColor clearColor]]; 35 | [self addSubview:backgroundViewDown]; 36 | 37 | //第一次显示的大图 38 | imageViewBig = [[UIImageView alloc ] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height )]; 39 | [imageViewBig setUserInteractionEnabled:YES]; 40 | [backgroundViewDown addSubview:imageViewBig]; 41 | 42 | // //点击大图event按钮显示效果 43 | // UITapGestureRecognizer *tapFirst = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(OnFirstTap)]; 44 | // [imageViewBig addGestureRecognizer:tapFirst]; 45 | 46 | //创建按钮 47 | roundButton = [[RoundButton alloc]initWithFrame:CGRectMake(roundButtonPosX , roundButtonPosY, roundBtnWH, roundBtnWH) backgroundProgressColor:[UIColor whiteColor] progressColor:[UIColor blueColor]]; 48 | [roundButton setUserInteractionEnabled:YES]; 49 | [roundButton setHidden:YES]; 50 | [backgroundViewDown addSubview:roundButton]; 51 | 52 | //添加手势(放大图片) 53 | UITapGestureRecognizer *tapButton = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(OnZoomImage)]; 54 | [roundButton addGestureRecognizer:tapButton]; 55 | } 56 | return self; 57 | } 58 | 59 | //图片数组 60 | -(void) setImageArray:(NSMutableArray*) array artId:(NSString *)ID 61 | { 62 | imageArray = [NSMutableArray arrayWithArray:array]; 63 | //从数组中删除第一个元素,将第一张图片显示在大图上 64 | [imageArray removeObjectAtIndex:0]; 65 | //数组为空时 66 | if ([imageArray count] ==0) 67 | { 68 | //只有一张图片 69 | if([array count] >= 1) 70 | { 71 | [imageViewBig sd_setImageWithURL:[array objectAtIndex:0] placeholderImage:[UIImage imageNamed:RecommendArticleDefaultImage] ]; 72 | } 73 | } 74 | else 75 | { 76 | [imageViewBig sd_setImageWithURL:[array objectAtIndex:0] placeholderImage:[UIImage imageNamed:RecommendArticleDefaultImage] ]; 77 | } 78 | //创建一个线程加载其他图片 79 | [self performSelectorInBackground:@selector(loadRoundButtonImage) withObject:nil]; 80 | } 81 | 82 | //加载网络图片 83 | -(void) loadRoundButtonImage 84 | { 85 | //异步加载圆按钮图片 86 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 87 | dispatch_async(dispatch_get_main_queue(), ^{ 88 | [roundButton setImageURL:[imageArray objectAtIndex:0] imageFrame:self.frame]; 89 | [roundButton setHidden:NO]; 90 | [roundButton setEnabled:YES]; 91 | }); 92 | }); 93 | } 94 | 95 | 96 | -(void) OnZoomImage 97 | { 98 | //隐藏按钮 99 | [roundButton setHidden:YES ]; 100 | [roundButton setEnabled:NO]; 101 | //放大按钮图片 102 | [self zoomImage:backgroundViewDown.frame image:roundButton.containerImageView]; 103 | } 104 | 105 | //放大图片 106 | -(void)zoomImage:(CGRect)frame image:(UIImageView*)zoomImageView 107 | { 108 | UIImage *image=zoomImageView.image; 109 | //图片缩小到的frame 110 | oldframe=CGRectMake(roundButtonPosX, roundButtonPosY, roundBtnWH, roundBtnWH); 111 | //新创建的图层和底层图片位置大小相同 112 | backgViewTop=[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 113 | backgViewTop.backgroundColor=[UIColor clearColor]; 114 | 115 | imageViewZoom = [[UIImageView alloc]initWithFrame:oldframe]; 116 | imageViewZoom.image=image; 117 | imageViewZoom.tag=1; 118 | [backgViewTop addSubview:imageViewZoom]; 119 | [backgroundViewDown addSubview:backgViewTop]; 120 | 121 | UITapGestureRecognizer *tapHideImage=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(hideImage:)]; 122 | [backgViewTop addGestureRecognizer: tapHideImage]; 123 | //图片放大动画 124 | [UIView animateWithDuration:deyTime delay:0.0f options:UIViewAnimationOptionCurveEaseOut animations:^{ 125 | imageViewZoom.frame=CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 126 | imageViewZoom.layer.masksToBounds = YES; 127 | imageViewZoom.layer.cornerRadius = 20; 128 | } completion:^(BOOL finished) 129 | { 130 | imageViewZoom.layer.masksToBounds = NO; 131 | imageViewZoom.layer.cornerRadius = 0; 132 | }]; 133 | 134 | [self performSelector:@selector(againCreateButton) withObject:nil afterDelay:deyTime]; 135 | } 136 | 137 | -(void)hideImage:(UITapGestureRecognizer*)tap 138 | { 139 | [NSThread sleepForTimeInterval:0.1]; 140 | if(buttonIndex == -1) 141 | return; 142 | //在关闭图片时,先隐藏按钮 143 | [topButton[buttonIndex--] setHidden:YES]; 144 | 145 | UIView *backgroundViewTop=tap.view; 146 | UIImageView *imageView=(UIImageView*)[tap.view viewWithTag:1]; 147 | [UIView animateWithDuration:deyTime animations:^{ 148 | imageView.frame=oldframe; 149 | imageView.layer.masksToBounds = YES; 150 | imageView.layer.cornerRadius = 20; 151 | } completion:^(BOOL finished) { 152 | [backgroundViewTop removeFromSuperview]; 153 | }]; 154 | //延迟执行显示按钮 155 | [self performSelector:@selector(showButton) withObject:nil afterDelay:0.6f]; 156 | } 157 | 158 | //显示按钮 159 | -(void)showButton 160 | { 161 | if (buttonIndex == 0 || buttonIndex== -1) 162 | { 163 | //再次点击放大图片时的数组索引 164 | buttonIndex =1; 165 | [UIView animateWithDuration:0.5f animations:^{ 166 | [roundButton setHidden:NO]; 167 | [roundButton setEnabled:YES]; 168 | }]; 169 | } 170 | else 171 | { 172 | [UIView animateWithDuration:0.5f animations:^{ 173 | [topButton[buttonIndex] setHidden:NO]; 174 | [topButton[buttonIndex] setEnabled:YES]; 175 | }]; 176 | } 177 | } 178 | 179 | -(void) againCreateButton 180 | { 181 | if(buttonIndex == -1) 182 | return; 183 | //如果是最后一张图则不在创建button,否则数组越界 184 | if ([imageArray count] == buttonIndex) 185 | return; 186 | //创建按钮 187 | topButton[buttonIndex] = [[RoundButton alloc]initWithFrame:CGRectMake(roundButtonPosX, roundButtonPosY, roundBtnWH,roundBtnWH) backgroundProgressColor:[UIColor whiteColor] progressColor:[UIColor blueColor]]; 188 | [ topButton[buttonIndex] setUserInteractionEnabled:YES]; 189 | [backgViewTop addSubview: topButton[buttonIndex]]; 190 | 191 | //添加手势 192 | UITapGestureRecognizer *tapTopButton = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(OnAgainZoom)]; 193 | [ topButton[buttonIndex] addGestureRecognizer:tapTopButton]; 194 | [ topButton[buttonIndex] setImageURL:[imageArray objectAtIndex:buttonIndex] imageFrame:self.frame ]; 195 | 196 | } 197 | 198 | -(void)OnAgainZoom 199 | { 200 | if(buttonIndex == -1) 201 | return; 202 | [topButton[buttonIndex] setHidden:YES]; 203 | [topButton[buttonIndex] setEnabled:NO]; 204 | [self zoomImage:backgroundViewDown.frame image: topButton[buttonIndex].containerImageView]; 205 | buttonIndex++; 206 | } 207 | 208 | 209 | ////第一张图点击事件 210 | -(void)OnFirstTap 211 | { 212 | // [self showAperture]; 213 | } 214 | 215 | ////点击第一张图显示光晕边框 216 | //-(void) showAperture 217 | //{ 218 | // CGRect pathFrame = CGRectMake(-CGRectGetMidX(roundButton.bounds), -CGRectGetMidY(roundButton.bounds), roundButton.bounds.size.width, roundButton.bounds.size.height); 219 | //// NSLog(@"%f %f",pathFrame.origin.x,pathFrame.origin.y); 220 | // 221 | // UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:pathFrame cornerRadius:roundButton.layer.cornerRadius]; 222 | // // accounts for left/right offset and contentOffset of scroll view 223 | // CGPoint shapePosition = [self convertPoint:roundButton.center fromView:nil]; 224 | // 225 | // CAShapeLayer *circleShape = [CAShapeLayer layer]; 226 | // circleShape.path = path.CGPath; 227 | // circleShape.position = shapePosition; 228 | // circleShape.fillColor = [UIColor clearColor].CGColor; 229 | // circleShape.opacity = 0; 230 | // circleShape.strokeColor = [UIColor blackColor].CGColor; 231 | // circleShape.lineWidth = 3; 232 | // 233 | // [self.layer addSublayer:circleShape]; 234 | // 235 | // CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 236 | // scaleAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; 237 | // scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.3f, 1.3f, 2)]; 238 | // 239 | // CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 240 | // alphaAnimation.fromValue = @1; 241 | // alphaAnimation.toValue = @0; 242 | // 243 | // CAAnimationGroup *animation = [CAAnimationGroup animation]; 244 | // animation.animations = @[scaleAnimation, alphaAnimation]; 245 | // animation.duration = 0.5f; 246 | // animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 247 | // [circleShape addAnimation:animation forKey:nil]; 248 | // 249 | //} 250 | 251 | 252 | 253 | 254 | @end 255 | -------------------------------------------------------------------------------- /如何使用: -------------------------------------------------------------------------------- 1 | [self.zoomImageView setImageArray:图片数组 artId:nil]; 2 | self.view addSubview:self.zoomImageView]; 3 | --------------------------------------------------------------------------------