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

//
// 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