|
//
// 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
|