美文网首页iOS开发程序员iOS学习笔记
iOS使用UIScrollView处理图片的缩放(图片浏览器)

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

作者: 九剑仙 | 来源:发表于2017-02-07 17:25 被阅读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,谢谢!

    相关文章

      网友评论

      本文标题:iOS使用UIScrollView处理图片的缩放(图片浏览器)

      本文链接:https://www.haomeiwen.com/subject/nzlmittx.html