iOS开发程序员iOS学习笔记

iOS使用UIScrollView处理图片的缩放(图片浏览器)

2017-02-07  本文已影响1732人  九剑仙

基础篇

首先我们来讨论一下使用UIScrollView来响应图片的放大、移动等用户交互手势。
UIScrollView有苹果自带的api,使用起来非常非常非常的简单,有码为证:
#import <UIKit/UIKit.h>
@protocol LLPhotoDelegate;
#define MaxSCale 3.0 //最大缩放比例
#define MinScale 1.0 //最小缩放比例

@interface LLPhoto : UIScrollView

@property (nonatomic, strong) UIImage *currentImage;
@property (nonatomic, assign) NSInteger currentIndex;
@property (nonatomic, weak)   id<LLPhotoDelegate> ll_delegate;
@end

@protocol LLPhotoDelegate <NSObject>

@optional
- (void)singleClickWithPhoto:(LLPhoto *)photo;

@end

#import "LLPhoto.h"

@interface LLPhoto ()<UIScrollViewDelegate>{
UIImageView *_imageView;
}
@end

@implementation LLPhoto

- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
    self.delegate = self;
    self.minimumZoomScale = MinScale;
    self.maximumZoomScale = MaxSCale;
    self.backgroundColor  = [UIColor blackColor];
    
    _imageView = [[UIImageView alloc] init];
    [self addSubview:_imageView];
    
    UITapGestureRecognizer *singleClick = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleClick:)];
    [self addGestureRecognizer:singleClick];
    
    UITapGestureRecognizer *doubleClick = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleClick:)];
    doubleClick.numberOfTapsRequired = 2;
    [self addGestureRecognizer:doubleClick];
    
    [singleClick requireGestureRecognizerToFail:doubleClick];
}
return self;
}

#pragma mark - 按图片比例适配imageView的frame
- (void)setCurrentImage:(UIImage *)currentImage {
_currentImage = currentImage;
[self layoutImageView];
}

- (void)layoutImageView {
CGRect imageFrame;
if (_currentImage.size.width > self.bounds.size.width || _currentImage.size.height > self.bounds.size.height) {
    CGFloat imageRatio = _currentImage.size.width/_currentImage.size.height;
    CGFloat photoRatio = self.bounds.size.width/self.bounds.size.height;
    
    if (imageRatio > photoRatio) {
        imageFrame.size = CGSizeMake(self.bounds.size.width, self.bounds.size.width/_currentImage.size.width*_currentImage.size.height);
        imageFrame.origin.x = 0;
        imageFrame.origin.y = (self.bounds.size.height-imageFrame.size.height)/2.0;
    }
    else {
        imageFrame.size = CGSizeMake(self.bounds.size.height/_currentImage.size.height*_currentImage.size.width, self.bounds.size.height);
        imageFrame.origin.x = (self.bounds.size.width-imageFrame.size.width)/2.0;
        imageFrame.origin.y = 0;
    }
}
else {
    imageFrame.size = _currentImage.size;
    imageFrame.origin.x = (self.bounds.size.width-_currentImage.size.width)/2.0;
    imageFrame.origin.y = (self.bounds.size.height-_currentImage.size.height)/2.0;
}
_imageView.frame = imageFrame;
_imageView.image = _currentImage;
}

#pragma mark - UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return _imageView;
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
CGFloat offsetX = (self.bounds.size.width>self.contentSize.width)?(self.bounds.size.width-self.contentSize.width)*0.5:0.0;
CGFloat offsetY = (self.bounds.size.height>self.contentSize.height)?(self.bounds.size.height-self.contentSize.height)*0.5:0.0;
_imageView.center = CGPointMake(scrollView.contentSize.width*0.5+offsetX, scrollView.contentSize.height*0.5+offsetY);
}

#pragma mark - 手势交互
- (void)singleClick:(UITapGestureRecognizer *)gestureRecognizer {
if ([self.ll_delegate respondsToSelector:@selector(singleClickWithPhoto:)]) {
    [self.ll_delegate singleClickWithPhoto:self];
}
else {
    [self removeFromSuperview];
}
}

- (void)doubleClick:(UITapGestureRecognizer *)gestureRecognizer {

if (self.zoomScale > MinScale) {
    [self setZoomScale:MinScale animated:YES];
} else {
    CGPoint touchPoint = [gestureRecognizer locationInView:_imageView];
    CGFloat newZoomScale = self.maximumZoomScale;
    CGFloat xsize = self.frame.size.width/newZoomScale;
    CGFloat ysize = self.frame.size.height/newZoomScale;
    [self zoomToRect:CGRectMake(touchPoint.x-xsize/2, touchPoint.y-ysize/2, xsize, ysize) animated:YES];
}
}

@end

使用的时候,几句代码就搞定了:

LLPhoto *photo = [[LLPhoto alloc] initWithFrame:self.view.bounds];
photo.currentImage = [UIImage imageNamed:@"123"];
[self.view addSubview:photo];

进阶篇

使用UIScrollViewUICollectionView制作一个图片浏览器
将基础篇中的scrollView封装为UIScrollView的子类,再使用UICollectionView展示<支持屏幕旋转>,感兴趣的同学可以尝试自己写一下,

github地址:https://github.com/wangzhaomeng/LLPhotoBrowser

这是一个长图.PNG 这是一个宽图.PNG 这是一个小图.PNG

觉得好,请给个star,谢谢!

上一篇下一篇

猜你喜欢

热点阅读