澎湃iPad上线版本

AsyncImageScrollView.m 20KB

    // // AsyncImageScrollView.m // ThePaperHD // // Created by scar1900 on 15/3/5. // Copyright (c) 2015年 scar1900. All rights reserved. // #import "AsyncImageScrollView.h" #import "YFGIFImageView.h" #import "UIImageView+WebCache.h" #define kMaxZoom 2.0 static const CGFloat activityIndicatorSize = 100.f; @interface AsyncImageScrollView()<RemoteDelegate,UIScrollViewDelegate> { UIImage* image; //图片的大小 CGSize imgSize; //缩放前大小 CGRect initRect; BOOL isZoom; BOOL isReChange; } @property(nonatomic, strong)UIImage* image; @property(nonatomic, readonly)NSString* imageName; @property(nonatomic, strong)UIActivityIndicatorView *activityView; @property(nonatomic, strong)YFGIFImageView *gifView; @end @implementation AsyncImageScrollView @synthesize imageView; @synthesize imageUrl; @synthesize isListMore; @synthesize imageDelegate; @synthesize gifView = _gifView; @synthesize gifData = _gifData; @synthesize imageSize = _imageSize; @synthesize index; - (id)init { self = [super init]; if (self) { self.isListMore = YES; isZoom = YES; } return self; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor clearColor]; [self.view addSubview:self.scrollView]; self.imageView = [[UIImageView alloc]initWithFrame:CGRectZero]; self.imageView.backgroundColor = [UIColor clearColor]; self.imageView.clipsToBounds = YES; self.imageView.userInteractionEnabled = YES; self.imageView.contentMode = UIViewContentModeScaleAspectFill; [self.scrollView addSubview:self.imageView]; [self.scrollView addSubview:self.gifView]; [self.scrollView addSubview:self.activityView]; UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; if (orientation == UIInterfaceOrientationLandscapeRight || orientation ==UIInterfaceOrientationLandscapeLeft) { self.scrollView.frame = CGRectMake(0, 0, 1024, 768); }else { self.scrollView.frame = CGRectMake(0, 0, 768, 1024); } if (imgSize.width == 0 && imgSize.height == 0) { imgSize = self.imageSize; } [self rechangeInitRdct]; [self.scrollView setContentSize:CGSizeMake(0, 0)]; self.imageView.center = self.scrollView.center; self.gifView.center = self.scrollView.center; UITapGestureRecognizer *twiceTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(twiceTap:)]; twiceTap.numberOfTapsRequired =2; twiceTap.delaysTouchesBegan = YES; twiceTap.numberOfTouchesRequired = 1; [self.imageView addGestureRecognizer:twiceTap]; UITapGestureRecognizer *gifTwiceTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(twiceTap:)]; gifTwiceTap.numberOfTapsRequired =2; gifTwiceTap.delaysTouchesBegan = YES; gifTwiceTap.numberOfTouchesRequired = 1; [self.gifView addGestureRecognizer:gifTwiceTap]; UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTap:)]; singleTap.numberOfTapsRequired =1; singleTap.numberOfTouchesRequired = 1; singleTap.delaysTouchesBegan = YES; [self.imageView addGestureRecognizer:singleTap]; UITapGestureRecognizer *gifSingleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTap:)]; gifSingleTap.numberOfTapsRequired =1; gifSingleTap.numberOfTouchesRequired = 1; gifSingleTap.delaysTouchesBegan = YES; [self.gifView addGestureRecognizer:gifSingleTap]; [singleTap requireGestureRecognizerToFail:twiceTap]; [gifSingleTap requireGestureRecognizerToFail:gifTwiceTap]; isReChange = NO; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (!self.imageView.image && self.gifView.hidden) { [self.activityView startAnimating]; [UIView animateWithDuration:0.3 animations:^{ self.activityView.alpha = 1.0f; }]; }else if (self.imageView.hidden && !self.gifData) { [self.activityView startAnimating]; [UIView animateWithDuration:0.3 animations:^{ self.activityView.alpha = 1.0f; }]; } } - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; if (isNotIOS8) { //bug:3892 UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; if (orientation == UIInterfaceOrientationLandscapeRight || orientation ==UIInterfaceOrientationLandscapeLeft) { self.scrollView.frame = CGRectMake(0, 0, 1024, 768); }else { self.scrollView.frame = CGRectMake(0, 0, 768, 1024); } } [self.activityView setFrame:CGRectMake((self.scrollView.bounds.size.width / 2) - (activityIndicatorSize / 2), (self.scrollView.bounds.size.height / 2) - (activityIndicatorSize / 2), activityIndicatorSize, activityIndicatorSize)]; } - (UIImage*) image { return image; } - (void)setImageSize:(CGSize)size { _imageSize = size; } - (UIScrollView*)scrollView { if (!_scrollView) { _scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds]; _scrollView.backgroundColor = [UIColor clearColor]; _scrollView.showsHorizontalScrollIndicator = NO; _scrollView.showsVerticalScrollIndicator = NO; _scrollView.bouncesZoom = YES; _scrollView.delegate = self; _scrollView.minimumZoomScale = 1.0; _scrollView.maximumZoomScale = kMaxZoom; } return _scrollView; } - (void)statusBarOrientationChange:(NSNotification *)notification { UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; if (orientation == UIInterfaceOrientationLandscapeRight || orientation ==UIInterfaceOrientationLandscapeLeft) { self.scrollView.frame = CGRectMake(0, 0, 1024, 768); }else { self.scrollView.frame = CGRectMake(0, 0, 768, 1024); } if (imgSize.width == 0 && imgSize.height == 0) { imgSize = self.imageSize; } [self rechangeInitRdct]; [self.scrollView setContentSize:CGSizeMake(0, 0)]; self.imageView.center = self.scrollView.center; self.gifView.center = self.scrollView.center; } - (UIActivityIndicatorView*)activityView { if (!_activityView) { _activityView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; _activityView.alpha = 1.0f; _activityView.hidesWhenStopped = YES; } return _activityView; } - (void)setContentWithFrame:(CGRect)frame { self.imageView.frame = frame; self.gifView.frame = frame; initRect = frame; } - (void) rechangeInitRdct { isReChange = YES; [self.scrollView setZoomScale:1 animated:YES]; CGSize scaledSize = imgSize; if (imgSize.height == 0 && imgSize.width == 0) { imgSize = self.imageSize; } if (imgSize.width > imgSize.height) { scaledSize.width = self.scrollView.bounds.size.width; CGFloat scale = imgSize.width/imgSize.height; scaledSize.height = self.scrollView.bounds.size.width/scale; if (scaledSize.height>self.scrollView.bounds.size.height) { scaledSize.height = self.scrollView.bounds.size.height; scaledSize.width = self.scrollView.bounds.size.height*scale; } }else { scaledSize.height = self.scrollView.bounds.size.height; CGFloat scale = imgSize.height/imgSize.width; scaledSize.width = self.scrollView.bounds.size.height/scale; if (scaledSize.width>self.scrollView.bounds.size.width) { scaledSize.width = self.scrollView.bounds.size.width; scaledSize.height = self.scrollView.bounds.size.width*scale; } } [self setContentWithFrame:CGRectMake(CGRectGetWidth(self.scrollView.bounds)/2-scaledSize.width/2, CGRectGetHeight(self.scrollView.bounds)/2-scaledSize.height/2, scaledSize.width, scaledSize.height)]; } - (void)setImage:(UIImage *)img { if (!img) { return; } BOOL isAnimate = NO; if (!self.imageView.image) { isAnimate = YES; } image = img; self.imageView.hidden = NO; self.gifView.hidden = YES; imgSize= img.size; self.imageSize = imgSize; CGSize scaledSize = imgSize; if (imgSize.width > imgSize.height) { scaledSize.width = self.scrollView.bounds.size.width; CGFloat scale = imgSize.width/imgSize.height; scaledSize.height = self.scrollView.bounds.size.width/scale; if (scaledSize.height>self.scrollView.bounds.size.height) { scaledSize.height = self.scrollView.bounds.size.height; scaledSize.width = self.scrollView.bounds.size.height*scale; } }else { scaledSize.height = self.scrollView.bounds.size.height; CGFloat scale = imgSize.height/imgSize.width; scaledSize.width = self.scrollView.bounds.size.height/scale; if (scaledSize.width>self.scrollView.bounds.size.width) { scaledSize.width = self.scrollView.bounds.size.width; scaledSize.height = self.scrollView.bounds.size.width*scale; } } [self setContentWithFrame:CGRectMake(CGRectGetWidth(self.scrollView.bounds)/2-scaledSize.width/2, CGRectGetHeight(self.scrollView.bounds)/2-scaledSize.height/2, scaledSize.width, scaledSize.height)]; self.imageView.center = self.scrollView.center; self.gifView.center = self.scrollView.center; self.imageView.image = img; [self.imageView setNeedsDisplay]; if (isAnimate) { [CoreAnimationEffect animationEaseIn:self.scrollView]; } [self.activityView stopAnimating]; [UIView animateWithDuration:0.3 animations:^{ self.activityView.alpha = 0.0f; }]; } - (void)setGifData:(NSData *)data { dispatch_async(dispatch_get_main_queue(), ^{ [self updateGif:data]; }); // [self performSelectorOnMainThread:@selector(updateGif:) withObject:data waitUntilDone:YES]; } - (void)updateGif:(NSData*)data { imgSize= self.imageSize; CGSize scaledSize = imgSize; if (imgSize.width > imgSize.height) { scaledSize.width = self.scrollView.bounds.size.width; CGFloat scale = imgSize.width/imgSize.height; scaledSize.height = self.scrollView.bounds.size.width/scale; if (scaledSize.height>self.scrollView.bounds.size.height) { scaledSize.height = self.scrollView.bounds.size.height; scaledSize.width = self.scrollView.bounds.size.height*scale; } }else { scaledSize.height = self.scrollView.bounds.size.height; CGFloat scale = imgSize.height/imgSize.width; scaledSize.width = self.scrollView.bounds.size.height/scale; if (scaledSize.width>self.scrollView.bounds.size.width) { scaledSize.width = self.scrollView.bounds.size.width; scaledSize.height = self.scrollView.bounds.size.width*scale; } } [self setContentWithFrame:CGRectMake(CGRectGetWidth(self.scrollView.bounds)/2-scaledSize.width/2, CGRectGetHeight(self.scrollView.bounds)/2-scaledSize.height/2, scaledSize.width, scaledSize.height)]; _gifData = data; self.imageView.hidden = YES; self.gifView.gifPath = self.imageName; self.gifView.hidden = NO; [self.gifView startGIF]; [self.activityView stopAnimating]; [UIView animateWithDuration:0.3 animations:^{ self.activityView.alpha = 0.0f; }]; } - (YFGIFImageView*)gifView { if (!_gifView) { _gifView = [[YFGIFImageView alloc]initWithFrame:CGRectZero]; _gifView.backgroundColor = [UIColor colorWithHexString:@"0xd9dcdd"]; _gifView.hidden = YES; _gifView.userInteractionEnabled = YES; } return _gifView; } - (NSString*)imageName { NSString* imageName = _imageId; // imageName = [imageName md5]; NSString *imagePathName = CachePath(imageName); return imagePathName; } - (NSString*)getFullPath:(NSString*)fileName { if ([[fileName pathExtension] length] > 0) { return ConfigPath([fileName lastPathComponent]); } else { return nil; } } - (void) setImageId:(NSString *)imageId { if ([_imageId isEqualToString:imageId]) { return; } _imageId = imageId; if (imageId.length <= 0) { self.image = nil; return; } if ([self.imageUrl isMatchedByRegex:@".gif"]) { if ([self.gifView isGIFPlaying]) { [self.gifView stopGIF]; } self.imageView.hidden = YES; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *data = [NSData dataWithContentsOfFile:self.imageName]; if (data) { self.gifData = data; }else { [self downLoadImage]; } }); }else { SDWebImageManager *imageManager = [SDWebImageManager sharedManager]; [imageManager downloadImageWithURL:[NSURL URLWithString:self.imageUrl] options:SDWebImageHighPriority progress:^(NSInteger receivedSize, NSInteger expectedSize) { } completed:^(UIImage *img, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { self.image = img; }]; } } - (void)readyToUpdateImage { if ([self.imageName isMatchedByRegex:@".gif"]) { NSData *data = [NSData dataWithContentsOfFile:self.imageName]; if (data) { self.gifData = data; }else { [self downLoadImage]; } }else { UIImage* IMAGE = [UIImage imageWithContentsOfFile:self.imageName]; if (IMAGE) { self.image = IMAGE; }else { [self downLoadImage]; } } } - (void)downLoadImage { self.image = nil; [Remote downloadFileAsync:self.imageUrl actionTag:1000+[getImageNumFromURL(self.imageUrl) intValue] filePath:self.imageName delegate:self]; } #pragma mark NetResponsDelegate - (void) remoteResponsSuccess:(int)actionTag withResponsData:(id)resData { NSData *imgData = [NSData dataWithContentsOfFile:resData]; if ([resData isEqualToString:self.imageName]) { if ([self.imageName isMatchedByRegex:@".gif"]) { self.gifData = imgData; }else { UIImage* IMAGE = [UIImage imageWithData:imgData]; self.image = IMAGE; } } } - (void) remoteResponsFailed:(int)actionTag withMessage:(NSString*)message resultCode:(NSString *)code{ NSLog(@"下载图片超时!"); self.image = nil; } - (void)startWaitCursor:(int)actionTag { } - (void)stopWaitCursor:(int)actionTag { } #pragma mark - scroll view delegate and method - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { [scrollView resignFirstResponder]; } - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { if (self.imageView.hidden) { return self.gifView; }else return self.imageView; } - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { if (scale == 1 && isReChange) { CGSize scaledSize = imgSize; if (imgSize.height == 0 && imgSize.width == 0) { imgSize = self.imageSize; } if (imgSize.width > imgSize.height) { scaledSize.width = self.scrollView.bounds.size.width; CGFloat scale = imgSize.width/imgSize.height; scaledSize.height = self.scrollView.bounds.size.width/scale; if (scaledSize.height>self.scrollView.bounds.size.height) { scaledSize.height = self.scrollView.bounds.size.height; scaledSize.width = self.scrollView.bounds.size.height*scale; } }else { scaledSize.height = self.scrollView.bounds.size.height; CGFloat scale = imgSize.height/imgSize.width; scaledSize.width = self.scrollView.bounds.size.height/scale; if (scaledSize.width>self.scrollView.bounds.size.width) { scaledSize.width = self.scrollView.bounds.size.width; scaledSize.height = self.scrollView.bounds.size.width*scale; } } [self setContentWithFrame:CGRectMake(CGRectGetWidth(self.scrollView.bounds)/2-scaledSize.width/2, CGRectGetHeight(self.scrollView.bounds)/2-scaledSize.height/2, scaledSize.width, scaledSize.height)]; [self.scrollView setContentSize:CGSizeMake(0, 0)]; self.imageView.center = self.scrollView.center; self.gifView.center = self.scrollView.center; isReChange = NO; } } -(void)scrollViewDidZoom:(UIScrollView *)scrollView { CGSize boundsSize = scrollView.bounds.size; CGRect imgFrame = self.imageView.frame; if (self.imageView.hidden) { imgFrame = self.gifView.frame; } CGSize contentSize = scrollView.contentSize; CGPoint centerPoint = CGPointMake(contentSize.width/2, contentSize.height/2); // center horizontally if (imgFrame.size.width <= boundsSize.width) { centerPoint.x = boundsSize.width/2; } // center vertically if (imgFrame.size.height <= boundsSize.height) { centerPoint.y = boundsSize.height/2; } if (self.imageView.hidden) { self.gifView.center = centerPoint; }else self.imageView.center = centerPoint; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (scrollView.isZooming) { return; } if (!scrollView.dragging) { return; } if (scrollView.decelerating) { return; } CGFloat contentOffsetX = scrollView.contentOffset.x; CGFloat offsetX = 0; if (contentOffsetX<0) { offsetX = contentOffsetX; }else if (contentOffsetX>768) { offsetX = contentOffsetX - 768; } } - (void)twiceTap:(UITapGestureRecognizer*)gestureRecognizer { if (self.scrollView.zoomScale>1) { [self.scrollView setZoomScale:1 animated:YES]; }else { CGRect zoomRect = [self zoomRectForScale:kMaxZoom withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; [self.scrollView zoomToRect:zoomRect animated:YES];//重新定义其cgrect的x和y值 } } - (void)singleTap:(UITapGestureRecognizer*)gestureRecognizer{ if ([self.imageDelegate respondsToSelector:@selector(singleTapGestureHandler)]) { [self.imageDelegate singleTapGestureHandler]; } } - (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center { CGRect zoomRect; // the zoom rect is in the content view's coordinates. // At a zoom scale of 1.0, it would be the size of the imageScrollView's bounds. // As the zoom scale decreases, so more content is visible, the size of the rect grows. zoomRect.size.height = [self.scrollView frame].size.height / scale; zoomRect.size.width = [self.scrollView frame].size.width / scale; // choose an origin so as to get the right center. zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0); // zoomRect.origin.x=center.x; // zoomRect.origin.y=center.y; zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0); return zoomRect; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; } @end