// // 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 () @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