You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
4.4 KiB
149 lines
4.4 KiB
// |
|
// XHZoomingImageView.m |
|
// XHImageViewer |
|
// |
|
// Created by 曾 宪华 on 14-2-17. |
|
// Copyright (c) 2014年 曾宪华 开发团队(http://iyilunba.com ) 本人QQ:543413507 本人QQ群(142557668). All rights reserved. |
|
// |
|
|
|
#import "XHZoomingImageView.h" |
|
|
|
@interface XHZoomingImageView () <UIScrollViewDelegate> |
|
|
|
@property (nonatomic, readwrite, strong) UIScrollView *scrollView; |
|
@property (nonatomic, strong) UIView *containerView; |
|
|
|
@end |
|
|
|
@implementation XHZoomingImageView |
|
|
|
- (void)_setup { |
|
self.clipsToBounds = YES; |
|
self.contentMode = UIViewContentModeScaleAspectFill; |
|
|
|
_scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; |
|
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; |
|
_scrollView.showsHorizontalScrollIndicator = NO; |
|
_scrollView.showsVerticalScrollIndicator = NO; |
|
_scrollView.delegate = self; |
|
|
|
_containerView = [[UIView alloc] initWithFrame:self.bounds]; |
|
[_scrollView addSubview:_containerView]; |
|
|
|
[self addSubview:_scrollView]; |
|
} |
|
|
|
- (void)awakeFromNib { |
|
[self _setup]; |
|
} |
|
|
|
- (id)initWithFrame:(CGRect)frame |
|
{ |
|
self = [super initWithFrame:frame]; |
|
if (self) { |
|
// Initialization code |
|
[self _setup]; |
|
} |
|
return self; |
|
} |
|
|
|
- (void)dealloc { |
|
[self.imageView removeObserver:self forKeyPath:@"image"]; |
|
} |
|
|
|
#pragma mark- Properties |
|
|
|
- (UIImage *)image { |
|
return _imageView.image; |
|
} |
|
|
|
- (void)setImage:(UIImage *)image { |
|
if(self.imageView == nil){ |
|
self.imageView = [UIImageView new]; |
|
self.imageView.clipsToBounds = YES; |
|
} |
|
self.imageView.image = image; |
|
} |
|
|
|
- (void)setImageView:(UIImageView *)imageView { |
|
if(imageView != _imageView) { |
|
[_imageView removeObserver:self forKeyPath:@"image"]; |
|
[_imageView removeFromSuperview]; |
|
|
|
_imageView = imageView; |
|
_imageView.frame = _imageView.bounds; |
|
|
|
[_imageView addObserver:self forKeyPath:@"image" options:0 context:nil]; |
|
|
|
[_containerView addSubview:_imageView]; |
|
|
|
_scrollView.zoomScale = 1; |
|
_scrollView.contentOffset = CGPointZero; |
|
_containerView.bounds = _imageView.bounds; |
|
|
|
[self resetZoomScale]; |
|
_scrollView.zoomScale = _scrollView.minimumZoomScale; |
|
[self scrollViewDidZoom:_scrollView]; |
|
} |
|
} |
|
|
|
- (BOOL)isViewing { |
|
return (_scrollView.zoomScale != _scrollView.minimumZoomScale); |
|
} |
|
|
|
#pragma mark- observe |
|
|
|
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { |
|
if(object == self.imageView) { |
|
[self imageDidChange]; |
|
} |
|
} |
|
|
|
- (void)imageDidChange { |
|
CGSize size = (self.imageView.image) ? self.imageView.image.size : self.bounds.size; |
|
CGFloat ratio = MIN(_scrollView.frame.size.width / size.width, _scrollView.frame.size.height / size.height); |
|
CGFloat W = ratio * size.width; |
|
CGFloat H = ratio * size.height; |
|
self.imageView.frame = CGRectMake(0, 0, W, H); |
|
|
|
_scrollView.zoomScale = 1; |
|
_scrollView.contentOffset = CGPointZero; |
|
_containerView.bounds = _imageView.bounds; |
|
|
|
[self resetZoomScale]; |
|
_scrollView.zoomScale = _scrollView.minimumZoomScale; |
|
[self scrollViewDidZoom:_scrollView]; |
|
} |
|
|
|
#pragma mark- Scrollview delegate |
|
|
|
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { |
|
return _containerView; |
|
} |
|
|
|
- (void)scrollViewDidZoom:(UIScrollView *)scrollView { |
|
CGFloat Ws = _scrollView.frame.size.width - _scrollView.contentInset.left - _scrollView.contentInset.right; |
|
CGFloat Hs = _scrollView.frame.size.height - _scrollView.contentInset.top - _scrollView.contentInset.bottom; |
|
CGFloat W = _containerView.frame.size.width; |
|
CGFloat H = _containerView.frame.size.height; |
|
|
|
CGRect rct = _containerView.frame; |
|
rct.origin.x = MAX((Ws-W)/2, 0); |
|
rct.origin.y = MAX((Hs-H)/2, 0); |
|
_containerView.frame = rct; |
|
} |
|
|
|
- (void)resetZoomScale { |
|
CGFloat Rw = _scrollView.frame.size.width / self.imageView.frame.size.width; |
|
CGFloat Rh = _scrollView.frame.size.height / self.imageView.frame.size.height; |
|
|
|
CGFloat scale = 1; |
|
Rw = MAX(Rw, _imageView.image.size.width / (scale * _scrollView.frame.size.width)); |
|
Rh = MAX(Rh, _imageView.image.size.height / (scale * _scrollView.frame.size.height)); |
|
|
|
_scrollView.contentSize = _imageView.frame.size; |
|
_scrollView.minimumZoomScale = 1; |
|
_scrollView.maximumZoomScale = MAX(MAX(Rw, Rh), 1); |
|
} |
|
|
|
@end
|
|
|