Brak opisu

XHImageViewer.m 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. //
  2. // XHImageViewer.m
  3. // XHImageViewer
  4. //
  5. // Created by 曾 宪华 on 14-2-17.
  6. // Copyright (c) 2014年 曾宪华 开发团队(http://iyilunba.com ) 本人QQ:543413507 本人QQ群(142557668). All rights reserved.
  7. //
  8. #import "XHImageViewer.h"
  9. #import "XHViewState.h"
  10. #import "XHZoomingImageView.h"
  11. @interface XHImageViewer () <UIScrollViewDelegate>
  12. @property (nonatomic, strong) UIScrollView *scrollView;
  13. @property (nonatomic, strong) NSArray *imgViews;
  14. @end
  15. @implementation XHImageViewer
  16. - (id)init {
  17. self = [self initWithFrame:CGRectZero];
  18. if (self) {
  19. [self _setup];
  20. }
  21. return self;
  22. }
  23. - (void)_setup {
  24. self.backgroundColor = [UIColor colorWithWhite:0.1 alpha:1];
  25. self.backgroundScale = 0.95;
  26. self.dismissInCenter = NO;
  27. UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didPan:)];
  28. pan.maximumNumberOfTouches = 1;
  29. [self addGestureRecognizer:pan];
  30. }
  31. - (id)initWithFrame:(CGRect)frame {
  32. self = [super initWithFrame:[[UIScreen mainScreen] bounds]];
  33. if (self) {
  34. [self _setup];
  35. }
  36. return self;
  37. }
  38. - (void)setImageViewsFromArray:(NSArray*)views {
  39. NSMutableArray *imgViews = [NSMutableArray array];
  40. for(id obj in views){
  41. if([obj isKindOfClass:[UIImageView class]]){
  42. [imgViews addObject:obj];
  43. UIImageView *view = obj;
  44. XHViewState *state = [XHViewState viewStateForView:view];
  45. [state setStateWithView:view];
  46. view.userInteractionEnabled = NO;
  47. [view removeFromSuperview];
  48. view.hidden = NO;
  49. }
  50. }
  51. _imgViews = [imgViews copy];
  52. }
  53. - (void)showWithImageViews:(NSArray*)views selectedView:(UIImageView*)selectedView {
  54. [self setImageViewsFromArray:views];
  55. if(_imgViews.count > 0){
  56. if(![selectedView isKindOfClass:[UIImageView class]] || ![_imgViews containsObject:selectedView]){
  57. selectedView = _imgViews[0];
  58. }
  59. self.pageLabel.hidden = _imgViews.count == 1 ? YES : NO;
  60. self.pageLabel.tag = _imgViews.count;
  61. [self showWithSelectedView:selectedView];
  62. }
  63. }
  64. #pragma mark- Properties
  65. - (void)setBackgroundColor:(UIColor *)backgroundColor {
  66. [super setBackgroundColor:[backgroundColor colorWithAlphaComponent:0]];
  67. }
  68. - (NSInteger)pageIndex {
  69. return (_scrollView.contentOffset.x / _scrollView.frame.size.width + 0.5);
  70. }
  71. #pragma mark- View management
  72. - (UIImageView *)currentView {
  73. return [_imgViews objectAtIndex:self.pageIndex];
  74. }
  75. - (void)showWithSelectedView:(UIImageView*)selectedView {
  76. [self showWithSelectedView:selectedView superView:nil];
  77. }
  78. - (void)showWithSelectedView:(UIImageView*)selectedView superView:(UIView *)superView{
  79. for(UIView *view in _scrollView.subviews) {
  80. [view removeFromSuperview];
  81. }
  82. const NSInteger currentPage = [_imgViews indexOfObject:selectedView];
  83. [self changePageLabelTextWithPage:currentPage];
  84. UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
  85. if(_scrollView == nil) {
  86. _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
  87. _scrollView.pagingEnabled = YES;
  88. _scrollView.showsHorizontalScrollIndicator = NO;
  89. _scrollView.showsVerticalScrollIndicator = NO;
  90. _scrollView.backgroundColor = [self.backgroundColor colorWithAlphaComponent:1];
  91. _scrollView.alpha = 0;
  92. _scrollView.delegate = self;
  93. }
  94. [self addSubview:_scrollView];
  95. // [self addSubview:self.pageControl];
  96. [self addSubview:self.pageLabel];
  97. [window addSubview:self];
  98. const CGFloat fullW = window.frame.size.width;
  99. const CGFloat fullH = window.frame.size.height;
  100. XHViewState *state = [XHViewState viewStateForView:selectedView];
  101. if (superView == nil) superView = state.superview;
  102. selectedView.frame = [window convertRect:selectedView.frame fromView:superView];
  103. if (!superView){
  104. selectedView.center = window.center;
  105. }
  106. [window addSubview:selectedView];
  107. [UIView animateWithDuration:0.3
  108. animations:^{
  109. _scrollView.alpha = 1;
  110. _pageLabel.alpha = 1;
  111. window.rootViewController.view.transform = CGAffineTransformMakeScale(self.backgroundScale, self.backgroundScale);
  112. selectedView.transform = CGAffineTransformIdentity;
  113. CGSize size = (selectedView.image) ? selectedView.image.size : selectedView.frame.size;
  114. CGFloat ratio = MIN(fullW / size.width, fullH / size.height);
  115. CGFloat W = ratio * size.width;
  116. CGFloat H = ratio * size.height;
  117. selectedView.frame = CGRectMake((fullW-W)/2, (fullH-H)/2, W, H);
  118. }
  119. completion:^(BOOL finished) {
  120. _scrollView.contentSize = CGSizeMake(_imgViews.count * fullW, 0);
  121. _scrollView.contentOffset = CGPointMake(currentPage * fullW, 0);
  122. UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedScrollView:)];
  123. [_scrollView addGestureRecognizer:gesture];
  124. for(UIImageView *view in _imgViews){
  125. view.transform = CGAffineTransformIdentity;
  126. CGSize size = (view.image) ? view.image.size : view.frame.size;
  127. CGFloat ratio = MIN(fullW / size.width, fullH / size.height);
  128. CGFloat W = ratio * size.width;
  129. CGFloat H = ratio * size.height;
  130. view.frame = CGRectMake((fullW-W)/2, (fullH-H)/2, W, H);
  131. XHZoomingImageView *tmp = [[XHZoomingImageView alloc] initWithFrame:CGRectMake([_imgViews indexOfObject:view] * fullW, 0, fullW, fullH)];
  132. tmp.imageView = view;
  133. [_scrollView addSubview:tmp];
  134. }
  135. }
  136. ];
  137. };
  138. - (void)prepareToDismiss {
  139. if([self.delegate respondsToSelector:@selector(imageViewer:willDismissWithpageIndex:)]) {
  140. [self.delegate imageViewer:self willDismissWithpageIndex:self.pageIndex];
  141. }
  142. }
  143. - (void)dismissWithAnimate {
  144. UIView *currentView = [self currentView];
  145. UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
  146. CGRect rct = currentView.frame;
  147. currentView.transform = CGAffineTransformIdentity;
  148. // XHViewState *state = [XHViewState viewStateForView:currentView];
  149. currentView.frame = [window convertRect:rct fromView:currentView.superview];
  150. [window addSubview:currentView];
  151. typeof(self) weakSelf = self;
  152. [UIView animateWithDuration:0.3
  153. animations:^{
  154. _scrollView.alpha = 0;
  155. _pageLabel.alpha = 0;
  156. currentView.alpha = 0;
  157. window.rootViewController.view.transform = CGAffineTransformIdentity;
  158. XHViewState *state = [XHViewState viewStateForView:currentView];
  159. CGPoint center = [window convertPoint:CGPointMake(CGRectGetMidX(state.frame), CGRectGetMidY(state.frame)) fromView:state.superview];
  160. if (weakSelf.dismissInCenter) center = window.center;
  161. currentView.center = center;
  162. currentView.transform = CGAffineTransformMakeScale(0.1, 0.1);
  163. }
  164. completion:^(BOOL finished) {
  165. [currentView removeFromSuperview];
  166. if ([weakSelf.delegate respondsToSelector:@selector(imageViewerDismissed:)]){
  167. [weakSelf.delegate imageViewerDismissed:weakSelf];
  168. }
  169. [weakSelf removeFromSuperview];
  170. }
  171. ];
  172. }
  173. - (void)changePageLabelTextWithPage:(NSInteger)currentPage{
  174. NSInteger totalCount = self.pageLabel.tag;
  175. self.pageLabel.text = [NSString stringWithFormat:@"%ld/%lu", (long)(currentPage + 1),(unsigned long)totalCount];
  176. }
  177. #pragma mark - scrollView delegate
  178. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
  179. UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
  180. const CGFloat fullW = window.frame.size.width;
  181. NSInteger currentPage = scrollView.contentOffset.x / fullW;
  182. [self changePageLabelTextWithPage:currentPage];
  183. }
  184. #pragma mark- Gesture events
  185. - (void)tappedScrollView:(UITapGestureRecognizer*)sender
  186. {
  187. [self prepareToDismiss];
  188. [self dismissWithAnimate];
  189. }
  190. - (void)didPan:(UIPanGestureRecognizer*)sender
  191. {
  192. static UIImageView *currentView = nil;
  193. if(sender.state == UIGestureRecognizerStateBegan){
  194. currentView = [self currentView];
  195. UIView *targetView = currentView.superview;
  196. while(![targetView isKindOfClass:[XHZoomingImageView class]]){
  197. targetView = targetView.superview;
  198. }
  199. if(((XHZoomingImageView *)targetView).isViewing){
  200. currentView = nil;
  201. }
  202. else{
  203. UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
  204. currentView.frame = [window convertRect:currentView.frame fromView:currentView.superview];
  205. [window addSubview:currentView];
  206. [self prepareToDismiss];
  207. }
  208. }
  209. if(currentView){
  210. if(sender.state == UIGestureRecognizerStateEnded){
  211. // if(_scrollView.alpha>0.5){
  212. // [self showWithSelectedView:currentView superView:currentView.superview];
  213. // }
  214. // else{
  215. [self dismissWithAnimate];
  216. // }
  217. currentView = nil;
  218. }
  219. else{
  220. CGPoint p = [sender translationInView:self];
  221. CGAffineTransform transform = CGAffineTransformMakeTranslation(0, p.y);
  222. transform = CGAffineTransformScale(transform, 1 - fabs(p.y)/1000, 1 - fabs(p.y)/1000);
  223. currentView.transform = transform;
  224. //
  225. // CGFloat r = 1-fabs(p.y)/200;
  226. // _scrollView.alpha = MAX(0, MIN(1, r));
  227. }
  228. }
  229. }
  230. //- (UIPageControl *)pageControl
  231. //{
  232. // if (_pageControl == nil) {
  233. // _pageControl = [[UIPageControl alloc]init];
  234. // _pageControl.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds) - 30);
  235. // _pageControl.hidesForSinglePage = YES;
  236. // _pageControl.alpha = 0;
  237. // }
  238. // return _pageControl;
  239. //}
  240. - (UILabel *)pageLabel{
  241. if (_pageLabel == nil) {
  242. _pageLabel = [[UILabel alloc]init];
  243. _pageLabel.textColor = [UIColor whiteColor];
  244. _pageLabel.font = [UIFont systemFontOfSize:16];
  245. _pageLabel.backgroundColor = [UIColor clearColor];
  246. _pageLabel.textAlignment = NSTextAlignmentCenter;
  247. _pageLabel.bounds = CGRectMake(0, 0, 200, 50);
  248. _pageLabel.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds) - 50);
  249. }
  250. return _pageLabel;
  251. }
  252. @end