JXHZoomImageView.m 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //
  2. // JXHZoomImageView.m
  3. // 我的社保
  4. //
  5. // Created by shanp on 2020/9/17.
  6. //
  7. #import "JXHZoomImageView.h"
  8. #import "JXHMacro.h"
  9. #import "JXHSystemShortcut.h"
  10. #import "JXHLayout.h"
  11. #import <JXHViewMeasure.h>
  12. #import <UIImageView+WebCache.h>
  13. @interface JXHZoomImageView ()<UIScrollViewDelegate> {
  14. CGFloat _maxZoom;
  15. CGFloat _verticalContentInset;
  16. }
  17. @end
  18. @implementation JXHZoomImageView
  19. - (instancetype)initWithTarget:(id)target action:(SEL)action {
  20. self = [super init];
  21. if (!self) return nil;
  22. [self initViewWithTarget:target action:action];
  23. [self createImageView];
  24. return self;
  25. }
  26. - (void)initViewWithTarget:(id)target action:(SEL)action {
  27. self.minimumZoomScale = 1.f;
  28. self.maximumZoomScale = _maxZoom = 2.f;
  29. self.showsHorizontalScrollIndicator = false;
  30. self.showsVerticalScrollIndicator = false;
  31. self.multipleTouchEnabled = true;
  32. self.delegate = self;
  33. UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(doubleTap:)];
  34. [doubleTap setNumberOfTapsRequired:2];
  35. [self addGestureRecognizer:doubleTap];
  36. UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:target action:action];
  37. [singleTap setNumberOfTapsRequired:1];
  38. [self addGestureRecognizer:singleTap];
  39. //只有当没有检测到doubleTap 或者 检测doubleTap失败,sigleTap才有效
  40. [singleTap requireGestureRecognizerToFail:doubleTap];
  41. }
  42. - (void)createImageView {
  43. _jxh_imageView = UIImageView.new;
  44. _jxh_imageView.frame = (CGRect){CGPointZero, (CGSize){jxh_viewWidth(self), jxh_viewHeight(self)}};
  45. _jxh_imageView.contentMode = UIViewContentModeScaleAspectFit;
  46. [self addSubview:_jxh_imageView];
  47. }
  48. #pragma mark - Action
  49. -(void)doubleTap:(UIGestureRecognizer *)gestureRecognizer{
  50. NSInteger newScale = [self zoomScale] == 1 ? _maxZoom : 1;
  51. [self setZoomScale:newScale animated:true];
  52. }
  53. - (void)setImageUrl:(NSURL *)url {
  54. @weakify(self)
  55. [_jxh_imageView sd_setImageWithURL:url completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
  56. @strongify(self)
  57. [self setImage:image];
  58. }];
  59. }
  60. - (void)setImage:(nullable UIImage *)image {
  61. if (jxh_viewWidth(self) == 0.f) {
  62. [self.superview layoutSubviews];
  63. }
  64. [self setZoomScale:1 animated:false];
  65. CGSize size;
  66. if (!image) {
  67. self.maximumZoomScale = _maxZoom = 2.f;
  68. _verticalContentInset = 0.f;
  69. size = (CGSize){jxh_viewWidth(self), jxh_viewHeight(self)};
  70. } else if (image.size.width / image.size.height >= jxh_viewWidth(self) / jxh_viewHeight(self)) {
  71. CGFloat height = image.size.height / image.size.width * jxh_viewWidth(self);
  72. _maxZoom = jxh_viewHeight(self) / height;
  73. if (_maxZoom < 2) {
  74. self.maximumZoomScale = _maxZoom = 2.0;
  75. } else {
  76. self.maximumZoomScale = _maxZoom * 2.0;
  77. }
  78. _verticalContentInset = (jxh_viewHeight(self) - height) / 2;
  79. size = (CGSize){jxh_viewWidth(self), jxh_viewHeight(self)};
  80. } else {
  81. self.maximumZoomScale = _maxZoom = 2.f;
  82. _verticalContentInset = 0.f;
  83. size = (CGSize){jxh_viewWidth(self), image.size.height / image.size.width * jxh_viewWidth(self)};
  84. }
  85. _jxh_imageView.frame = (CGRect){CGPointZero, size};
  86. [self setContentSize:_jxh_imageView.frame.size];
  87. [self setContentInset:UIEdgeInsetsZero];
  88. _jxh_imageView.image = image;
  89. }
  90. #pragma mark - Delegate
  91. - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  92. return _jxh_imageView;
  93. }
  94. - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
  95. }
  96. - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
  97. if (scale > 1) {
  98. CGFloat height = _jxh_imageView.image.size.height / _jxh_imageView.image.size.width * jxh_viewWidth(_jxh_imageView);
  99. CGFloat y = 0.f;
  100. if (height < jxh_screenHeight()) {
  101. y = (jxh_screenHeight() - height) / 2;
  102. }
  103. _jxh_imageView.frame = (CGRect){(CGPoint){0, y}, _jxh_imageView.frame.size};
  104. scrollView.contentInset = UIEdgeInsetsMake(- _verticalContentInset * scale, 0, - _verticalContentInset * scale, 0);
  105. } else {
  106. _jxh_imageView.frame = (CGRect){CGPointZero, _jxh_imageView.frame.size};
  107. [scrollView setContentInset:UIEdgeInsetsZero];
  108. }
  109. }
  110. - (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  111. CGFloat height = _jxh_imageView.image.size.height / _jxh_imageView.image.size.width * jxh_viewWidth(_jxh_imageView);
  112. CGFloat y = 0.f;
  113. if (height < jxh_screenHeight()) {
  114. y = (jxh_screenHeight() - height) / 2;
  115. }
  116. _jxh_imageView.frame = (CGRect){(CGPoint){0, y}, _jxh_imageView.frame.size};
  117. scrollView.contentInset = UIEdgeInsetsMake(- _verticalContentInset * scrollView.zoomScale, 0, - _verticalContentInset * scrollView.zoomScale, 0);
  118. }
  119. //- (CGRect)zoomRectForScale:(NSInteger)scale withCenter:(CGPoint)center {
  120. //
  121. // CGRect zoomRect;
  122. //
  123. // zoomRect.size.height = [self frame].size.height / scale;
  124. // zoomRect.size.width = [self frame].size.width / scale;
  125. //
  126. // zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0) - (jxh_screenWidth() - _imageView.frame.size.width) / 2;
  127. // zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0) - (jxh_screenHeight() - _imageView.frame.size.height) / 2;
  128. // return zoomRect;
  129. //}
  130. @end