XHZoomingImageView.m 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // XHZoomingImageView.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 "XHZoomingImageView.h"
  9. @interface XHZoomingImageView () <UIScrollViewDelegate>
  10. @property (nonatomic, readwrite, strong) UIScrollView *scrollView;
  11. @property (nonatomic, strong) UIView *containerView;
  12. @end
  13. @implementation XHZoomingImageView
  14. - (void)_setup {
  15. self.clipsToBounds = YES;
  16. self.contentMode = UIViewContentModeScaleAspectFill;
  17. _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
  18. _scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  19. _scrollView.showsHorizontalScrollIndicator = NO;
  20. _scrollView.showsVerticalScrollIndicator = NO;
  21. _scrollView.delegate = self;
  22. _containerView = [[UIView alloc] initWithFrame:self.bounds];
  23. [_scrollView addSubview:_containerView];
  24. [self addSubview:_scrollView];
  25. }
  26. - (void)awakeFromNib {
  27. [self _setup];
  28. }
  29. - (id)initWithFrame:(CGRect)frame
  30. {
  31. self = [super initWithFrame:frame];
  32. if (self) {
  33. // Initialization code
  34. [self _setup];
  35. }
  36. return self;
  37. }
  38. - (void)dealloc {
  39. [self.imageView removeObserver:self forKeyPath:@"image"];
  40. }
  41. #pragma mark- Properties
  42. - (UIImage *)image {
  43. return _imageView.image;
  44. }
  45. - (void)setImage:(UIImage *)image {
  46. if(self.imageView == nil){
  47. self.imageView = [UIImageView new];
  48. self.imageView.clipsToBounds = YES;
  49. }
  50. self.imageView.image = image;
  51. }
  52. - (void)setImageView:(UIImageView *)imageView {
  53. if(imageView != _imageView){
  54. [_imageView removeObserver:self forKeyPath:@"image"];
  55. [_imageView removeFromSuperview];
  56. _imageView = imageView;
  57. _imageView.frame = _imageView.bounds;
  58. [_imageView addObserver:self forKeyPath:@"image" options:0 context:nil];
  59. [_containerView addSubview:_imageView];
  60. _scrollView.zoomScale = 1;
  61. _scrollView.contentOffset = CGPointZero;
  62. _containerView.bounds = _imageView.bounds;
  63. [self resetZoomScale];
  64. _scrollView.zoomScale = _scrollView.minimumZoomScale;
  65. [self scrollViewDidZoom:_scrollView];
  66. }
  67. }
  68. - (BOOL)isViewing {
  69. return (_scrollView.zoomScale != _scrollView.minimumZoomScale);
  70. }
  71. #pragma mark- observe
  72. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
  73. if(object==self.imageView){
  74. [self imageDidChange];
  75. }
  76. }
  77. - (void)imageDidChange {
  78. CGSize size = (self.imageView.image) ? self.imageView.image.size : self.bounds.size;
  79. CGFloat ratio = MIN(_scrollView.frame.size.width / size.width, _scrollView.frame.size.height / size.height);
  80. CGFloat W = ratio * size.width;
  81. CGFloat H = ratio * size.height;
  82. self.imageView.frame = CGRectMake(0, 0, W, H);
  83. _scrollView.zoomScale = 1;
  84. _scrollView.contentOffset = CGPointZero;
  85. _containerView.bounds = _imageView.bounds;
  86. [self resetZoomScale];
  87. _scrollView.zoomScale = _scrollView.minimumZoomScale;
  88. [self scrollViewDidZoom:_scrollView];
  89. }
  90. #pragma mark- Scrollview delegate
  91. - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
  92. return _containerView;
  93. }
  94. - (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  95. CGFloat Ws = _scrollView.frame.size.width - _scrollView.contentInset.left - _scrollView.contentInset.right;
  96. CGFloat Hs = _scrollView.frame.size.height - _scrollView.contentInset.top - _scrollView.contentInset.bottom;
  97. CGFloat W = _containerView.frame.size.width;
  98. CGFloat H = _containerView.frame.size.height;
  99. CGRect rct = _containerView.frame;
  100. rct.origin.x = MAX((Ws-W)/2, 0);
  101. rct.origin.y = MAX((Hs-H)/2, 0);
  102. _containerView.frame = rct;
  103. }
  104. - (void)resetZoomScale {
  105. CGFloat Rw = _scrollView.frame.size.width / self.imageView.frame.size.width;
  106. CGFloat Rh = _scrollView.frame.size.height / self.imageView.frame.size.height;
  107. CGFloat scale = 1;
  108. Rw = MAX(Rw, _imageView.image.size.width / (scale * _scrollView.frame.size.width));
  109. Rh = MAX(Rh, _imageView.image.size.height / (scale * _scrollView.frame.size.height));
  110. _scrollView.contentSize = _imageView.frame.size;
  111. _scrollView.minimumZoomScale = 1;
  112. _scrollView.maximumZoomScale = MAX(MAX(Rw, Rh), 1);
  113. }
  114. @end