iOS使用UIScrollView處理圖片的縮放(圖片瀏覽器)

基礎篇

首先我們來討論一下使用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展示<支持屏幕旋轉(zhuǎn)>,感興趣的同學可以嘗試自己寫一下,

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

這是一個長圖.PNG
這是一個寬圖.PNG
這是一個小圖.PNG

覺得好,請給個star,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容