经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
iOS- XKZoomingView 简单的图片预览,支持横屏【手势:单击、双击、放大缩小】
来源:cnblogs  作者:macro小K  时间:2018/11/28 9:45:26  对本文有异议

XKZoomingView.h

  1. #import <UIKit/UIKit.h>
  2.  
  3. @interface XKZoomingView : UIScrollView
  4. /**
  5. 本地图片
  6. */
  7. @property (nonatomic, strong) UIImage *mainImage;
  8. /**
  9. 图片显示
  10. */
  11. @property (nonatomic, strong) UIImageView *mainImageView;
  12. @end

XKZoomingView.m

  1. #import "XKZoomingView.h"
  2. @interface XKZoomingView()<UIScrollViewDelegate>
  3. /**
  4. 当前图片偏移量
  5. */
  6. @property (nonatomic,assign) CGPoint currPont;
  7. @end
  8. @implementation XKZoomingView
  9. - (instancetype)init{
  10. self = [super init];
  11. if (self) {
  12. [self setup];
  13. }
  14. return self;
  15. }
  16. - (instancetype)initWithFrame:(CGRect)frame{
  17. self = [super initWithFrame:frame];
  18. if (self) {
  19. [self setup];
  20. }
  21. return self;
  22. }
  23. - (void)setup{
  24. self.backgroundColor = [[UIColor grayColor]colorWithAlphaComponent:0.2];
  25. self.delegate = self;
  26. self.showsHorizontalScrollIndicator = NO;
  27. self.showsVerticalScrollIndicator = NO;
  28. self.decelerationRate = UIScrollViewDecelerationRateFast;
  29. self.maximumZoomScale = 3;
  30. self.minimumZoomScale = 1;
  31. self.alwaysBounceHorizontal = NO;
  32. self.alwaysBounceVertical = NO;
  33. self.layer.masksToBounds = YES;
  34. if (@available(iOS 11.0, *)) {
  35. self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  36. }
  37. [self addSubview:self.mainImageView];
  38. _currPont = CGPointZero;
  39. ///监听屏幕旋转
  40. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
  41. ///单击
  42. UITapGestureRecognizer *tapSingle = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapSingleSponse:)];
  43. //设置手势属性
  44. tapSingle.numberOfTapsRequired = 1;
  45. tapSingle.delaysTouchesEnded = NO;
  46. [self.mainImageView addGestureRecognizer:tapSingle];
  47. ///双击
  48. UITapGestureRecognizer *tapDouble = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapDoubleSponse:)];
  49. //设置手势属性
  50. tapDouble.numberOfTapsRequired = 2;
  51. [self.mainImageView addGestureRecognizer:tapDouble];
  52. ///避免手势冲突
  53. [tapSingle requireGestureRecognizerToFail:tapDouble];
  54. }
  55. #pragma mark - layoutSubviews
  56. - (void)layoutSubviews{
  57. [super layoutSubviews];
  58. ///放大或缩小中
  59. if (self.zooming || self.zoomScale != 1.0 || self.zoomBouncing) {
  60. return;
  61. }
  62. ///设置图片尺寸
  63. if (_mainImage) {
  64. CGRect imgRect = [self getImageViewFrame];
  65. self.mainImageView.frame = imgRect;
  66. ///设置content size
  67. if (CGRectGetHeight(imgRect) > CGRectGetHeight(self.frame)) {
  68. [self setContentSize:CGSizeMake(CGRectGetWidth(self.frame), CGRectGetHeight(imgRect))];
  69. }
  70. else{
  71. [self setContentSize:CGSizeMake(CGRectGetWidth(self.frame), CGRectGetHeight(self.frame))];
  72. }
  73. }
  74. }
  75. - (void)setMainImage:(UIImage *)mainImage{
  76. _mainImage = mainImage;
  77. self.mainImageView.image = _mainImage;
  78. [self setContentOffset:CGPointMake(0, 0)];
  79. [self setNeedsLayout];
  80. }
  81. /**
  82. 根据图片原始大小,获取图片显示大小
  83. @return CGRect
  84. */
  85. - (CGRect)getImageViewFrame{
  86. if (_mainImage) {
  87. CGRect imageRect;
  88. CGFloat scWidth = self.frame.size.width;
  89. CGFloat scHeight = self.frame.size.height;
  90. ///width
  91. if (_mainImage.size.width > scWidth) {
  92. imageRect.size.width = scWidth;
  93. CGFloat ratioHW = _mainImage.size.height/_mainImage.size.width;
  94. imageRect.size.height = ratioHW * imageRect.size.width;
  95. imageRect.origin.x = 0;
  96. }
  97. else{
  98. imageRect.size.width = _mainImage.size.width;
  99. imageRect.size.height = _mainImage.size.height;
  100. imageRect.origin.x = (scWidth - imageRect.size.width)/2;
  101. }
  102. ///height
  103. if (imageRect.size.height > scHeight) {
  104. imageRect.origin.y = 0;
  105. }
  106. else{
  107. imageRect.origin.y = (scHeight - imageRect.size.height)/2;
  108. }
  109. return imageRect;
  110. }
  111. return CGRectZero;
  112. }
  113. /**
  114. 获取点击位置后所需的偏移量【目的是呈现点击位置在试图上】
  115. @param location 点击位置
  116. */
  117. - (void)zoomingOffset:(CGPoint)location{
  118. CGFloat lo_x = location.x * self.zoomScale;
  119. CGFloat lo_y = location.y * self.zoomScale;
  120. CGFloat off_x;
  121. CGFloat off_y;
  122. ///off_x
  123. if (lo_x < CGRectGetWidth(self.frame)/2) {
  124. off_x = 0;
  125. }
  126. else if (lo_x > self.contentSize.width - CGRectGetWidth(self.frame)/2){
  127. off_x = self.contentSize.width - CGRectGetWidth(self.frame);
  128. }
  129. else{
  130. off_x = lo_x - CGRectGetWidth(self.frame)/2;
  131. }
  132. ///off_y
  133. if (lo_y < CGRectGetHeight(self.frame)/2) {
  134. off_y = 0;
  135. }
  136. else if (lo_y > self.contentSize.height - CGRectGetHeight(self.frame)/2){
  137. if (self.contentSize.height <= CGRectGetHeight(self.frame)) {
  138. off_y = 0;
  139. }
  140. else{
  141. off_y = self.contentSize.height - CGRectGetHeight(self.frame);
  142. }
  143. }
  144. else{
  145. off_y = lo_y - CGRectGetHeight(self.frame)/2;
  146. }
  147. [self setContentOffset:CGPointMake(off_x, off_y)];
  148. }
  149. #pragma mark - 重置图片
  150. - (void)resetImageViewState{
  151. self.zoomScale = 1;
  152. _mainImage = nil;;
  153. self.mainImageView.image = nil;
  154. }
  155. #pragma mark - 变量
  156. - (UIImageView *)mainImageView {
  157. if (!_mainImageView) {
  158. _mainImageView = [UIImageView new];
  159. _mainImageView.image = nil;
  160. _mainImageView.contentMode = UIViewContentModeScaleAspectFit;
  161. _mainImageView.userInteractionEnabled = YES;
  162. }
  163. return _mainImageView;
  164. }
  165. #pragma mark - 单击
  166. - (void)tapSingleSponse:(UITapGestureRecognizer *)singleTap{
  167. if (!self.mainImageView.image) {
  168. return;
  169. }
  170. if (self.zoomScale != 1) {
  171. [UIView animateWithDuration:0.2 animations:^{
  172. self.zoomScale = 1;
  173. } completion:^(BOOL finished) {
  174. [self setContentOffset:_currPont animated:YES];
  175. }];
  176. }
  177. }
  178. #pragma mark - 双击
  179. - (void)tapDoubleSponse:(UITapGestureRecognizer *)doubleTap{
  180. if (!self.mainImageView.image) {
  181. return;
  182. }
  183. CGPoint point = [doubleTap locationInView:self.mainImageView];
  184. if (self.zoomScale == 1) {
  185. [UIView animateWithDuration:0.2 animations:^{
  186. self.zoomScale = 2.0;
  187. [self zoomingOffset:point];
  188. }];
  189. }
  190. else{
  191. [UIView animateWithDuration:0.2 animations:^{
  192. self.zoomScale = 1;
  193. } completion:^(BOOL finished) {
  194. [self setContentOffset:_currPont animated:YES];
  195. }];
  196. }
  197. }
  198. #pragma mark - UIScrollViewDelegate
  199. - (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  200. if (!self.mainImageView.image) {
  201. return;
  202. }
  203. CGRect imageViewFrame = self.mainImageView.frame;
  204. CGFloat width = imageViewFrame.size.width,
  205. height = imageViewFrame.size.height,
  206. sHeight = scrollView.bounds.size.height,
  207. sWidth = scrollView.bounds.size.width;
  208. if (height > sHeight) {
  209. imageViewFrame.origin.y = 0;
  210. } else {
  211. imageViewFrame.origin.y = (sHeight - height) / 2.0;
  212. }
  213. if (width > sWidth) {
  214. imageViewFrame.origin.x = 0;
  215. } else {
  216. imageViewFrame.origin.x = (sWidth - width) / 2.0;
  217. }
  218. self.mainImageView.frame = imageViewFrame;
  219. }
  220. - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  221. return self.mainImageView;
  222. }
  223. - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
  224. if (self.isZooming || self.zoomScale != 1) {
  225. return;
  226. }
  227. _currPont = scrollView.contentOffset;
  228. }
  229. #pragma mark - 监听屏幕旋转通知
  230. - (void)statusBarOrientationChange:(NSNotification *)notification{
  231. self.zoomScale = 1;
  232. }
  233. - (void)dealloc{
  234. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
  235. }
  236. @end

USE

  1. XKZoomingView *zoomView = [[XKZoomingView alloc]init];
  2. zoomView.frame = self.view.bounds;
  3. zoomView.mainImage = [UIImage imageNamed:@""];
  4. [self.view addSubview:zoomView];

 ELSE

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号