123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- //
- // XHImageViewer.m
- // XHImageViewer
- //
- // Created by 曾 宪华 on 14-2-17.
- // Copyright (c) 2014年 曾宪华 开发团队(http://iyilunba.com ) 本人QQ:543413507 本人QQ群(142557668). All rights reserved.
- //
- #import "XHImageViewer.h"
- #import "XHViewState.h"
- #import "XHZoomingImageView.h"
- @interface XHImageViewer () <UIScrollViewDelegate>
- @property (nonatomic, strong) UIScrollView *scrollView;
- @property (nonatomic, strong) NSArray *imgViews;
- @end
- @implementation XHImageViewer
- - (id)init {
- self = [self initWithFrame:CGRectZero];
- if (self) {
- [self _setup];
- }
- return self;
- }
- - (void)_setup {
- self.backgroundColor = [UIColor colorWithWhite:0.1 alpha:1];
- self.backgroundScale = 0.95;
- self.dismissInCenter = NO;
-
- UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didPan:)];
- pan.maximumNumberOfTouches = 1;
- [self addGestureRecognizer:pan];
- }
- - (id)initWithFrame:(CGRect)frame {
- self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
- if (self) {
- [self _setup];
- }
- return self;
- }
- - (void)setImageViewsFromArray:(NSArray*)views {
- NSMutableArray *imgViews = [NSMutableArray array];
- for(id obj in views){
- if([obj isKindOfClass:[UIImageView class]]){
- [imgViews addObject:obj];
-
- UIImageView *view = obj;
-
- XHViewState *state = [XHViewState viewStateForView:view];
- [state setStateWithView:view];
-
- view.userInteractionEnabled = NO;
- [view removeFromSuperview];
- view.hidden = NO;
- }
- }
- _imgViews = [imgViews copy];
- }
- - (void)showWithImageViews:(NSArray*)views selectedView:(UIImageView*)selectedView {
- [self setImageViewsFromArray:views];
-
- if(_imgViews.count > 0){
- if(![selectedView isKindOfClass:[UIImageView class]] || ![_imgViews containsObject:selectedView]){
- selectedView = _imgViews[0];
- }
-
- self.pageLabel.hidden = _imgViews.count == 1 ? YES : NO;
- self.pageLabel.tag = _imgViews.count;
-
- [self showWithSelectedView:selectedView];
- }
- }
- #pragma mark- Properties
- - (void)setBackgroundColor:(UIColor *)backgroundColor {
- [super setBackgroundColor:[backgroundColor colorWithAlphaComponent:0]];
- }
- - (NSInteger)pageIndex {
- return (_scrollView.contentOffset.x / _scrollView.frame.size.width + 0.5);
- }
- #pragma mark- View management
- - (UIImageView *)currentView {
- return [_imgViews objectAtIndex:self.pageIndex];
- }
- - (void)showWithSelectedView:(UIImageView*)selectedView {
-
- [self showWithSelectedView:selectedView superView:nil];
-
- }
- - (void)showWithSelectedView:(UIImageView*)selectedView superView:(UIView *)superView{
- for(UIView *view in _scrollView.subviews) {
- [view removeFromSuperview];
- }
-
- const NSInteger currentPage = [_imgViews indexOfObject:selectedView];
- [self changePageLabelTextWithPage:currentPage];
-
- UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
-
- if(_scrollView == nil) {
- _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
- _scrollView.pagingEnabled = YES;
- _scrollView.showsHorizontalScrollIndicator = NO;
- _scrollView.showsVerticalScrollIndicator = NO;
- _scrollView.backgroundColor = [self.backgroundColor colorWithAlphaComponent:1];
- _scrollView.alpha = 0;
- _scrollView.delegate = self;
- }
-
-
- [self addSubview:_scrollView];
- // [self addSubview:self.pageControl];
- [self addSubview:self.pageLabel];
- [window addSubview:self];
-
- const CGFloat fullW = window.frame.size.width;
- const CGFloat fullH = window.frame.size.height;
-
-
- XHViewState *state = [XHViewState viewStateForView:selectedView];
-
- if (superView == nil) superView = state.superview;
-
- selectedView.frame = [window convertRect:selectedView.frame fromView:superView];
- if (!superView){
- selectedView.center = window.center;
- }
-
- [window addSubview:selectedView];
-
- [UIView animateWithDuration:0.3
- animations:^{
- _scrollView.alpha = 1;
- _pageLabel.alpha = 1;
- window.rootViewController.view.transform = CGAffineTransformMakeScale(self.backgroundScale, self.backgroundScale);
-
- selectedView.transform = CGAffineTransformIdentity;
-
- CGSize size = (selectedView.image) ? selectedView.image.size : selectedView.frame.size;
- CGFloat ratio = MIN(fullW / size.width, fullH / size.height);
- CGFloat W = ratio * size.width;
- CGFloat H = ratio * size.height;
- selectedView.frame = CGRectMake((fullW-W)/2, (fullH-H)/2, W, H);
- }
- completion:^(BOOL finished) {
- _scrollView.contentSize = CGSizeMake(_imgViews.count * fullW, 0);
- _scrollView.contentOffset = CGPointMake(currentPage * fullW, 0);
-
- UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedScrollView:)];
- [_scrollView addGestureRecognizer:gesture];
-
- for(UIImageView *view in _imgViews){
- view.transform = CGAffineTransformIdentity;
-
- CGSize size = (view.image) ? view.image.size : view.frame.size;
- CGFloat ratio = MIN(fullW / size.width, fullH / size.height);
- CGFloat W = ratio * size.width;
- CGFloat H = ratio * size.height;
- view.frame = CGRectMake((fullW-W)/2, (fullH-H)/2, W, H);
-
- XHZoomingImageView *tmp = [[XHZoomingImageView alloc] initWithFrame:CGRectMake([_imgViews indexOfObject:view] * fullW, 0, fullW, fullH)];
- tmp.imageView = view;
-
- [_scrollView addSubview:tmp];
- }
-
- }
- ];
- };
- - (void)prepareToDismiss {
-
- if([self.delegate respondsToSelector:@selector(imageViewer:willDismissWithpageIndex:)]) {
- [self.delegate imageViewer:self willDismissWithpageIndex:self.pageIndex];
- }
- }
- - (void)dismissWithAnimate {
- UIView *currentView = [self currentView];
- UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
-
- CGRect rct = currentView.frame;
- currentView.transform = CGAffineTransformIdentity;
- // XHViewState *state = [XHViewState viewStateForView:currentView];
- currentView.frame = [window convertRect:rct fromView:currentView.superview];
- [window addSubview:currentView];
-
-
- typeof(self) weakSelf = self;
- [UIView animateWithDuration:0.3
- animations:^{
- _scrollView.alpha = 0;
- _pageLabel.alpha = 0;
- currentView.alpha = 0;
- window.rootViewController.view.transform = CGAffineTransformIdentity;
-
- XHViewState *state = [XHViewState viewStateForView:currentView];
- CGPoint center = [window convertPoint:CGPointMake(CGRectGetMidX(state.frame), CGRectGetMidY(state.frame)) fromView:state.superview];
- if (weakSelf.dismissInCenter) center = window.center;
- currentView.center = center;
- currentView.transform = CGAffineTransformMakeScale(0.1, 0.1);
- }
- completion:^(BOOL finished) {
- [currentView removeFromSuperview];
- if ([weakSelf.delegate respondsToSelector:@selector(imageViewerDismissed:)]){
- [weakSelf.delegate imageViewerDismissed:weakSelf];
- }
- [weakSelf removeFromSuperview];
- }
- ];
- }
- - (void)changePageLabelTextWithPage:(NSInteger)currentPage{
-
- NSInteger totalCount = self.pageLabel.tag;
- self.pageLabel.text = [NSString stringWithFormat:@"%ld/%lu", (long)(currentPage + 1),(unsigned long)totalCount];
- }
- #pragma mark - scrollView delegate
- - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
-
- UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
- const CGFloat fullW = window.frame.size.width;
- NSInteger currentPage = scrollView.contentOffset.x / fullW;
- [self changePageLabelTextWithPage:currentPage];
- }
- #pragma mark- Gesture events
- - (void)tappedScrollView:(UITapGestureRecognizer*)sender
- {
- [self prepareToDismiss];
- [self dismissWithAnimate];
- }
- - (void)didPan:(UIPanGestureRecognizer*)sender
- {
- static UIImageView *currentView = nil;
-
- if(sender.state == UIGestureRecognizerStateBegan){
- currentView = [self currentView];
-
- UIView *targetView = currentView.superview;
- while(![targetView isKindOfClass:[XHZoomingImageView class]]){
- targetView = targetView.superview;
- }
-
- if(((XHZoomingImageView *)targetView).isViewing){
- currentView = nil;
- }
- else{
- UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
- currentView.frame = [window convertRect:currentView.frame fromView:currentView.superview];
- [window addSubview:currentView];
-
- [self prepareToDismiss];
- }
- }
-
- if(currentView){
- if(sender.state == UIGestureRecognizerStateEnded){
- // if(_scrollView.alpha>0.5){
- // [self showWithSelectedView:currentView superView:currentView.superview];
- // }
- // else{
- [self dismissWithAnimate];
- // }
- currentView = nil;
- }
- else{
- CGPoint p = [sender translationInView:self];
-
- CGAffineTransform transform = CGAffineTransformMakeTranslation(0, p.y);
- transform = CGAffineTransformScale(transform, 1 - fabs(p.y)/1000, 1 - fabs(p.y)/1000);
- currentView.transform = transform;
- //
- // CGFloat r = 1-fabs(p.y)/200;
- // _scrollView.alpha = MAX(0, MIN(1, r));
- }
- }
- }
- //- (UIPageControl *)pageControl
- //{
- // if (_pageControl == nil) {
- // _pageControl = [[UIPageControl alloc]init];
- // _pageControl.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds) - 30);
- // _pageControl.hidesForSinglePage = YES;
- // _pageControl.alpha = 0;
- // }
- // return _pageControl;
- //}
- - (UILabel *)pageLabel{
- if (_pageLabel == nil) {
- _pageLabel = [[UILabel alloc]init];
- _pageLabel.textColor = [UIColor whiteColor];
- _pageLabel.font = [UIFont systemFontOfSize:16];
- _pageLabel.backgroundColor = [UIColor clearColor];
- _pageLabel.textAlignment = NSTextAlignmentCenter;
- _pageLabel.bounds = CGRectMake(0, 0, 200, 50);
- _pageLabel.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds) - 50);
- }
- return _pageLabel;
- }
- @end
|