LZImageBrowserSubView.m 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //
  2. // LZImageBrowserSubView.m
  3. // LZImageDetail
  4. //
  5. // Created by shenzhenshihua on 2018/4/28.
  6. // Copyright © 2018年 shenzhenshihua. All rights reserved.
  7. //
  8. #import "LZImageBrowserSubView.h"
  9. #import "LZImageBrowserModel.h"
  10. #import "LZImageBrowserHeader.h"
  11. #import <SDWebImage/UIImageView+WebCache.h>
  12. @interface LZImageBrowserSubView ()<UIScrollViewDelegate>
  13. @property(nonatomic,strong)LZImageBrowserModel * imageBrowserModel;
  14. @property(nonatomic,strong)UIScrollView * subScrollView;
  15. @property(nonatomic,strong)UIImageView * subImageView;
  16. @property(nonatomic,assign)NSInteger touchFingerNumber;
  17. @end
  18. @implementation LZImageBrowserSubView
  19. - (id)initWithFrame:(CGRect)frame ImageBrowserModel:(LZImageBrowserModel *)imageBrowserModel {
  20. self = [super initWithFrame:frame];
  21. if (self) {
  22. self.imageBrowserModel = imageBrowserModel;
  23. [self initView];
  24. }
  25. return self;
  26. }
  27. - (void)initView {
  28. [self addSubview:self.subScrollView];
  29. [self.subScrollView addSubview:self.subImageView];
  30. //加入 点击事件 单击 与 双击
  31. UITapGestureRecognizer * singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)];
  32. [self addGestureRecognizer:singleTap];
  33. UITapGestureRecognizer * doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapAction:)];
  34. doubleTap.numberOfTapsRequired = 2;
  35. [singleTap requireGestureRecognizerToFail:doubleTap];
  36. [self addGestureRecognizer:doubleTap];
  37. _imageBrowserModel.bigScrollView = self.subScrollView;
  38. _imageBrowserModel.bigImageView = self.subImageView;
  39. __weak typeof (self)ws = self;
  40. [self.subImageView sd_setImageWithURL:[NSURL URLWithString:_imageBrowserModel.urlStr] placeholderImage:_imageBrowserModel.smallImageView.image completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
  41. if (!error) {
  42. [ws updateSubScrollViewSubImageView];
  43. }
  44. }];
  45. [self updateSubScrollViewSubImageView];
  46. }
  47. //单击 退出
  48. - (void)singleTapAction:(UITapGestureRecognizer *)singleTap {
  49. if ([self.delegate respondsToSelector:@selector(imageBrowserSubViewSingleTapWithModel:)]) {
  50. [self.delegate imageBrowserSubViewSingleTapWithModel:_imageBrowserModel];
  51. }
  52. }
  53. //双击 局部放大 或者 变成正常大小
  54. - (void)doubleTapAction:(UITapGestureRecognizer *)doubleTap {
  55. if (self.subScrollView.zoomScale > 1.0) {
  56. //已经放大过了 就变成正常大小
  57. [self.subScrollView setZoomScale:1.0 animated:YES];
  58. } else {
  59. //如果是正常大小 就 局部放大
  60. CGPoint touchPoint = [doubleTap locationInView:self.subImageView];
  61. CGFloat maxZoomScale = self.subScrollView.maximumZoomScale;
  62. CGFloat width = self.frame.size.width / maxZoomScale;
  63. CGFloat height = self.frame.size.height / maxZoomScale;
  64. [self.subScrollView zoomToRect:CGRectMake(touchPoint.x - width/2, touchPoint.y = height/2, width, height) animated:YES];
  65. }
  66. }
  67. - (void)updateSubScrollViewSubImageView {
  68. [self.subScrollView setZoomScale:1.0 animated:NO];
  69. CGFloat imageW = _imageBrowserModel.bigImageSize.width;
  70. CGFloat imageH = _imageBrowserModel.bigImageSize.height;
  71. CGFloat height = Screen_Width * imageH/imageW;
  72. if (imageH/imageW > Screen_Height/Screen_Width) {
  73. //长图
  74. self.subImageView.frame =CGRectMake(0, 0, Screen_Width, height);
  75. } else {
  76. self.subImageView.frame =CGRectMake(0, Screen_Height/2 - height/2, Screen_Width, height);
  77. }
  78. self.subScrollView.contentSize = CGSizeMake(Screen_Width, height);
  79. }
  80. #pragma mark -scrollView delegate
  81. - (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  82. return self.subImageView;
  83. }
  84. - (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  85. CGFloat offsetX = (scrollView.frame.size.width > scrollView.contentSize.width) ? (scrollView.frame.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
  86. CGFloat offsetY = (scrollView.frame.size.height > scrollView.contentSize.height) ? (scrollView.frame.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
  87. self.subImageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY);
  88. }
  89. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  90. UIPanGestureRecognizer * subScrollViewPan = [scrollView panGestureRecognizer];
  91. _touchFingerNumber = subScrollViewPan.numberOfTouches;
  92. _subScrollView.clipsToBounds = NO;
  93. }
  94. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  95. CGFloat contentOffsetY = scrollView.contentOffset.y;
  96. //只有是一根手指事件才做出响应。
  97. if (contentOffsetY < 0 && _touchFingerNumber == 1) {
  98. [self changeSizeCenterY:contentOffsetY];
  99. }
  100. }
  101. - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
  102. CGFloat contentOffsetY = scrollView.contentOffset.y;
  103. if ((contentOffsetY<0 && _touchFingerNumber==1) && (velocity.y<0 && fabs(velocity.y)>fabs(velocity.x))) {
  104. //如果是向下滑动才触发消失的操作。
  105. if ([self.delegate respondsToSelector:@selector(imageBrowserSubViewSingleTapWithModel:)]) {
  106. [self.delegate imageBrowserSubViewSingleTapWithModel:_imageBrowserModel];
  107. }
  108. } else {
  109. [self changeSizeCenterY:0.0];
  110. CGFloat offsetX = (scrollView.frame.size.width > scrollView.contentSize.width) ? (scrollView.frame.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
  111. CGFloat offsetY = (scrollView.frame.size.height > scrollView.contentSize.height) ? (scrollView.frame.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
  112. self.subImageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY);
  113. }
  114. _touchFingerNumber = 0;
  115. self.subScrollView.clipsToBounds = YES;
  116. }
  117. - (void)changeSizeCenterY:(CGFloat)contentOffsetY {
  118. //contentOffsetY 为负值
  119. CGFloat multiple = (Screen_Height + contentOffsetY*1.75)/Screen_Height;
  120. if ([self.delegate respondsToSelector:@selector(imageBrowserSubViewTouchMoveChangeMainViewAlpha:)]) {
  121. [self.delegate imageBrowserSubViewTouchMoveChangeMainViewAlpha:multiple];
  122. }
  123. multiple = multiple>0.4?multiple:0.4;
  124. self.subScrollView.transform = CGAffineTransformMakeScale(multiple, multiple);
  125. self.subScrollView.center = CGPointMake(Screen_Width/2, Screen_Height/2 - contentOffsetY*0.5);
  126. }
  127. #pragma mark -lazy
  128. - (UIScrollView *)subScrollView {
  129. if (_subScrollView == nil) {
  130. _subScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, Screen_Width, Screen_Height)];
  131. _subScrollView.delegate = self;
  132. _subScrollView.bouncesZoom = YES;
  133. _subScrollView.maximumZoomScale = 2.5;//最大放大倍数
  134. _subScrollView.minimumZoomScale = 1.0;//最小缩小倍数
  135. _subScrollView.multipleTouchEnabled = YES;
  136. _subScrollView.scrollsToTop = NO;
  137. _subScrollView.contentSize = CGSizeMake(Screen_Width, Screen_Height);
  138. _subScrollView.userInteractionEnabled = YES;
  139. _subScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  140. _subScrollView.delaysContentTouches = NO;//默认yes 设置NO则无论手指移动的多么快,始终都会将触摸事件传递给内部控件;
  141. _subScrollView.canCancelContentTouches = NO; // 默认是yes
  142. _subScrollView.alwaysBounceVertical = YES;//设置上下回弹
  143. _subScrollView.showsVerticalScrollIndicator = NO;
  144. _subScrollView.showsHorizontalScrollIndicator = NO;
  145. if (@available(iOS 11.0, *)) {
  146. //表示只在ios11以上的版本执行
  147. _subScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  148. }
  149. }
  150. return _subScrollView;
  151. }
  152. - (UIImageView *)subImageView {
  153. if (_subImageView == nil) {
  154. _subImageView = [[UIImageView alloc] init];
  155. _subImageView.contentMode = UIViewContentModeScaleAspectFit;
  156. }
  157. return _subImageView;
  158. }
  159. /*
  160. // Only override drawRect: if you perform custom drawing.
  161. // An empty implementation adversely affects performance during animation.
  162. - (void)drawRect:(CGRect)rect {
  163. // Drawing code
  164. }
  165. */
  166. @end