相册图片浏览器(模仿path),效果类似微信朋友圈,效果有优化。

最近公司需要新需求,就是做图片的浏览器。看了看微信、微博、陌陌还有一些其他的应用,不得不说国内软件做的还是比较生硬的。最后看了看path的效果比较不错,就参照他实现功能了。起初从出现消失动画(这也是刚开始最为难我的地方,找位置好难啊),图片轮播加载等开始做的。说多无用,直接上代码吧,在它上面还有一个父类, 就是有个初始化方法, 大家看懂思路就好了,不明白的问我~~

.h文件

@protocol FullSizeImagesControlDelegate;


@interface FullSizeImagesControl : FullSizeImageControl<UIScrollViewDelegate, UIGestureRecognizerDelegate>

@property (nonatomic, strong) id<FullSizeImagesControlDelegate, FullSizeImageControlDelegate> delegate;

@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIPageControl *pageControl;

@property (nonatomic, strong) NSArray *imageURLs;
@property (nonatomic, strong) NSMutableArray *imageViews;
@property (nonatomic, strong) NSMutableArray *scrollViews;
@property (nonatomic, strong) NSArray *images;

@property (nonatomic, assign) NSInteger currentPage;

- (void)showImages:(NSArray *)images URLs:(NSArray *)imageURLs fromView:(UIView *)view index:(NSInteger )index completed:(void (^)(void))completed;
- (void)showImage:(UIImage *)image imageURL:(NSString *)imageURL fromView:(UIView *)view;

@end



@protocol FullSizeImagesControlDelegate <FullSizeImageControlDelegate>

@optional

- (NSArray *)sourceViews;

- (void)fullSizeImagesControlDidLongPress:(NSInteger )index;

@end
.m文件

#import "FullSizeImagesControl.h"

static CGFloat kMargin = 20.0;

@implementation FullSizeImagesControl

#pragma mark - property

- (UIScrollView *)scrollView {
	
	if (!_scrollView) {
		
		_scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero];
		_scrollView.pagingEnabled = YES;
		_scrollView.bounces = YES;
		_scrollView.delegate = self;
		_scrollView.showsHorizontalScrollIndicator = NO;
		_scrollView.showsVerticalScrollIndicator = NO;
	}
	return _scrollView;
}

- (UIPageControl *)pageControl {
	
	if (!_pageControl) {
		
		_pageControl = [[UIPageControl alloc]initWithFrame:CGRectZero];
		_pageControl.currentPageIndicatorTintColor = [DR6StyleManager globalStyleManager].windowTintColor;
		_pageControl.pageIndicatorTintColor = [DR6StyleManager globalStyleManager].imageBackgroundColor;
		_pageControl.userInteractionEnabled = NO;
	}
	return _pageControl;
}

- (NSMutableArray *)imageViews {
	
	if (!_imageViews) {
		_imageViews = [NSMutableArray arrayWithCapacity:0];
	}
	return _imageViews;
}

- (NSMutableArray *)scrollViews {
	
	if (!_scrollViews) {
		_scrollViews = [NSMutableArray arrayWithCapacity:0];
	}
	return _scrollViews;
}

- (void)setImageURLs:(NSArray *)imageURLs {
	_imageURLs = imageURLs;
	
	self.scrollView.frame = CGRectMake(0, 0, self.frame.size.width + kMargin, self.frame.size.height);
	self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * imageURLs.count, 0);
	[self addSubview:self.scrollView];
	
	for (int i = 0; i < imageURLs.count; i++) {
		
		UIImageView *imageView = [[UIImageView alloc] init];
		imageView.contentMode = UIViewContentModeScaleAspectFit;
		__weak typeof(UIImageView) *weakimageView = imageView;
		
		UIScrollView *imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(self.scrollView.frame.size.width * i, 0, self.frame.size.width, self.frame.size.height)];
		imageScrollView.delegate  = self;
		imageScrollView.bounces = YES;
		
		imageScrollView.showsHorizontalScrollIndicator = NO;
		imageScrollView.showsVerticalScrollIndicator = NO;
		
		if (self.images.count > i) {
			imageView.image = self.images[i];
			imageView.frame = CGRectMake(0, 0, imageScrollView.width, imageScrollView.height);
			imageView.center = imageScrollView.center;
		}
		
		UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
		activityView.center = imageScrollView.center;
		activityView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
		[activityView startAnimating];
		
		[imageView addSubview:activityView];
		[imageScrollView addSubview:imageView];
		
		[imageView setImageWithURL:imageURLs[i] placeholderImage:imageView.image completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
			
			if (image) {
				
				if ((self.height - weakimageView.image.size.height * self.width / weakimageView.image.size.width) >= 0) {
					weakimageView.frame = CGRectMake(0, (self.height - weakimageView.image.size.height * self.width / weakimageView.image.size.width) / 2, self.width, weakimageView.image.size.height * self.width / weakimageView.image.size.width);
				} else {
					weakimageView.frame = CGRectMake((self.width - self.height / weakimageView.image.size.height * weakimageView.image.size.width) / 2.0, 0, self.height/ weakimageView.image.size.height * weakimageView.image.size.width, self.height);
				}
				
				imageScrollView.maximumZoomScale = (self.scrollView.height / weakimageView.height > 1.5 ? self.height / weakimageView.height : (self.width / weakimageView.width >= 2.0 ? self.width / weakimageView.width : 2.0));
				imageScrollView.minimumZoomScale = 1.0;
				
				[self.imageViews addObject:weakimageView];
				
				[activityView stopAnimating];
			}
			
			
		}];
		
		UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
		UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
		doubleTapGesture.numberOfTapsRequired = 2;
		[singleTapGesture requireGestureRecognizerToFail:doubleTapGesture];
		
		[imageScrollView addGestureRecognizer:doubleTapGesture];
		[imageScrollView addGestureRecognizer:singleTapGesture];
		
		[imageScrollView setContentSize:CGSizeMake(imageView.width, imageView.height)];
		
		[self.scrollView addSubview:imageScrollView];
		[self.scrollViews addObject:imageScrollView];
	}
	
	CGFloat pageControlHeight = 10.0;
	CGFloat margin = 30.0;
	
	if (imageURLs.count > 1) {
		self.pageControl.frame = CGRectMake(0, self.frame.size.height - margin, self.frame.size.width, pageControlHeight);
		[self addSubview:_pageControl];
	}
	
}

#pragma mark - public

- (void)showImages:(NSArray *)images URLs:(NSArray *)imageURLs fromView:(UIView *)view index:(NSInteger )index completed:(void (^)(void))completed {
	
	UIImage *presentingImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:imageURLs[index]];
	if (imageURLs.count <= 0 && !presentingImage) {
		return;
	}
	
	self.pageControl.numberOfPages = imageURLs.count;
	self.pageControl.currentPage = index;
	
	self.images = images;
	
	[self.imageView setImageWithURL:[NSURL URLWithString:imageURLs[index]]];
	
	[self addSubview:self.imageView];
	
	UIView *keyWindow = [UIApplication sharedApplication].keyWindow;
	CGRect rect = [view.superview convertRect:view.frame toView:keyWindow];
	self.imageView.frame = rect;
	
	self.alpha = 0;
	self.backgroundColor = [UIColor clearColor];
	
	[keyWindow addSubview:self];
	
	CGFloat startRadius = view.layer.cornerRadius;
	CGFloat endRadius = 0;
	if (startRadius) {
		self.imageView.layer.cornerRadius = startRadius;
	}
	
	[UIView animateWithDuration:0.2
						  delay:0
						options:UIViewAnimationOptionCurveLinear
					 animations:^{
						 
						 self.alpha = 1;
						 self.backgroundColor = [UIColor blackColor];
						 
					 } completion:^(BOOL finished) {
						 
						 CGFloat duration = 0.3;
						 
						 if (startRadius) {
							 
							 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
							 
							 animation.delegate = self;
							 
							 animation.fromValue = @(startRadius);
							 animation.toValue = @(endRadius);
							 animation.duration = duration;
							 [self.imageView.layer addAnimation:animation forKey:@"cornerRadius"];
							 self.imageView.layer.cornerRadius = 0;
						 }
						 
						 self.imageView.contentMode = UIViewContentModeScaleAspectFit;
						 
						 if (!self.imageView.image) {
							 
							 self.imageURLs = imageURLs;
							 self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width * index, 0);
							 self.pageControl.currentPage = index;
							 self.imageView.image = self.images[index];
							 self.imageView.frame = [self finalRectForImage:self.images[index]];
							 self.imageView.hidden = YES;
							 return ;
						 }
						 
						 [UIView animateWithDuration:duration
											   delay:0
											 options:7 << 16
										  animations:^{
											  
											  self.imageView.frame = [self finalRectForImage:presentingImage];
										  } completion:^(BOOL finished) {
											  
											  self.imageView.layer.cornerRadius = endRadius;
											  if (![NSStringFromCGRect(self.imageView.frame) isEqualToString:NSStringFromCGRect([self finalRectForImage:presentingImage])]) {
												  return ;
											  }
											  
											  self.imageURLs = imageURLs;
											  self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width * index, 0);
											  self.pageControl.currentPage = index;
											  self.currentPage = index;
											  self.imageView.hidden = YES;
											  
											  completed();
										  }];
					 }];
	
	
}

- (void)showImage:(UIImage *)image imageURL:(NSString *)imageURL fromView:(UIView *)view {

	[self showImages:[NSArray arrayWithObject:image] URLs:[NSArray arrayWithObject:imageURL] fromView:view index:0 completed:^{
		
	}];
}


- (void)pressed:(id)sender {
	
	UIView *sourceView = nil;
	
	if ([self.delegate respondsToSelector:@selector(sourceView)]) {
		sourceView = [self.delegate sourceView];
	} else if ([self.delegate respondsToSelector:@selector(sourceViews)]) {
		
		if (self.pageControl.currentPage < [self.delegate sourceViews].count) {
			sourceView = (UIView *)[self.delegate sourceViews][self.pageControl.currentPage];
		}
		
	}
	
	self.imageView.hidden = NO;
	[self.scrollView removeFromSuperview];
	[self.pageControl removeFromSuperview];
	self.imageView.contentMode = UIViewContentModeScaleAspectFill;
	//    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
	
	CGFloat duration = 0.3;
	CGFloat startRadius = sourceView.layer.cornerRadius;
	CGFloat endRadius = 0;
	
	UIView *rootView = [UIApplication sharedApplication].keyWindow;
	CGRect rect = self.imageView.frame;
	
	if (sourceView) {
		rect = [sourceView.superview convertRect:sourceView.frame toView:rootView];
		if (startRadius) {
			self.imageView.layer.cornerRadius = endRadius;
			
			CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
			
			animation.fromValue = @(endRadius);
			animation.toValue = @(startRadius);
			animation.duration = duration;
			[self.imageView.layer addAnimation:animation forKey:@"cornerRadius"];
			self.imageView.layer.cornerRadius = startRadius;
		}
	}
	
	[UIView animateWithDuration:duration
						  delay:0
						options:7 << 16
					 animations:^{
						 
						 [self imageShrink];
						 self.imageView.frame = rect;
					 } completion:^(BOOL finished) {
						 
						 [UIView animateWithDuration:0.2
											   delay:0
											 options:UIViewAnimationOptionCurveLinear
										  animations:^{
											  
											  self.alpha = 0;
											  self.backgroundColor = [UIColor clearColor];
										  } completion:^(BOOL finished) {
											  
											  [self removeFromSuperview];
										  }];
					 }];
}

- (void)longPressed:(UILongPressGestureRecognizer *)presser {
	
	if (presser.state == UIGestureRecognizerStateBegan && [self.delegate respondsToSelector:@selector(fullSizeImagesControlDidLongPress:)]) {
		[self.delegate fullSizeImagesControlDidLongPress:self.pageControl.currentPage];
	}
}

- (void)handleDoubleTap:(UIGestureRecognizer *)gesture {
	
	float newScale;
	UIScrollView *scrollView = (UIScrollView *)gesture.view;
	
	if (scrollView.zoomScale == 1.0) {
		newScale = scrollView.maximumZoomScale;
	}
	else{
		newScale = 1.0 / scrollView.maximumZoomScale;
	}
	
	CGRect zoomRect = [self zoomRectForScale:newScale withCenter: [gesture locationInView:(UIScrollView *)gesture.view]];
	[(UIScrollView *)gesture.view zoomToRect:zoomRect animated:YES];
	
}

- (void)handleSingleTap:(UIGestureRecognizer *)gesture {
	
	UIScrollView *scrollView = (UIScrollView *)gesture.view;
	
	if (scrollView.zoomScale != 1.0) {
		self.imageView.frame = CGRectMake(-scrollView.contentOffset.x, -scrollView.contentOffset.y, scrollView.contentSize.width, scrollView.contentSize.height);
	}
	
	self.imageView.hidden = NO;
	[self.scrollView removeFromSuperview];
	[self.pageControl removeFromSuperview];
	[self pressed:self];
}

#pragma mark - private

- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
	
	CGRect zoomRect;
	zoomRect.size.height = self.frame.size.height / scale;
	zoomRect.size.width  = self.frame.size.width  / scale;
	zoomRect.origin.x = center.x - zoomRect.size.width / 2.0;
	zoomRect.origin.y = center.y - zoomRect.size.height / 2.0;
	return zoomRect;
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
	
	[_pageControl setCurrentPage:_scrollView.contentOffset.x / _scrollView.frame.size.width];
	
	if (self.currentPage == self.pageControl.currentPage) {
		return;
	}
	
	if (self.scrollView == scrollView) {
		
		for (UIScrollView *imagescrollView in self.scrollViews) {
			
			if ([imagescrollView isKindOfClass:[UIScrollView class]]) {
				
				imagescrollView.zoomScale = 1.0;
			}
		}
		self.currentPage = self.pageControl.currentPage;
	}
	
	if (self.pageControl.currentPage < _imageViews.count) {
		
		UIImageView *imageView = _imageViews[self.pageControl.currentPage];
		self.imageView.image = imageView.image;
		self.imageView.frame = imageView.frame;
	}
}


#pragma mark - UIScrollViewZoom

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
	if (scrollView != self.scrollView) {
		if (self.imageViews.count == self.scrollViews.count) {
			UIImageView *imageView = [self.imageViews objectAtIndex:[self.scrollViews indexOfObject:scrollView]];
			return imageView;
		}
	}
	return nil;
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
	
	CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
	(scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
	CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
	(scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
	
	UIImageView *imageView = [self.imageViews objectAtIndex:[self.scrollViews indexOfObject:scrollView]];
	imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY);
}

@end



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值