iOS 图片缩放

需求分析

在App的图片查看中常见有以下功能:


双击缩放

图片随用户手指的点击,会进行相应区域的缩放,虽然这个简单的功能十分常见,实现起来并不难,但常在群里见人问,故略作说明:

视图层次

在此图片显示中 之需要一个UIScrollView和一个UIImageView即可,在一个scrollView 上添加一个imageView,在显示图片的时间,根据图片尺寸调整scrollView的contentSize以便能完全显示并可以移动查看。

    - (void)setupUI {
self.view.backgroundColor = [UIColor blackColor];
self.automaticallyAdjustsScrollViewInsets = NO;
_scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
_scrollView.maximumZoomScale = 2.0;
_scrollView.minimumZoomScale = 1.0;
_scrollView.delegate = self;
[self.view addSubview:_scrollView];
//显示照片的imageView
_imageView = [[UIImageView alloc]init];
_imageView.userInteractionEnabled = YES;
_imageView.center = self.view.center;
//长按保存手势
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[_imageView addGestureRecognizer:longPress];
[_scrollView addSubview:_imageView];
//双击缩放手势
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)];
doubleTap.numberOfTapsRequired = 2;
[_imageView addGestureRecognizer:doubleTap];
        
}

图片加载显示:

    - (void)loadImage {

[_imageView sd_setImageWithURL:_url placeholderImage:_placeholder options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {
    //图片下载进度 为后期要求加进度条预留
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
    //如果图片下载失败 则直接返回
    if (image == nil) {
        return ;
    }
    _imageView.image = image;
    //设置imageView的位置
    [self setImagePosition:image];
}];
}

图片imageView的位置显示:

- (void)setImagePosition:(UIImage *)image {
CGSize size = [self imageSizeWithScreen:image];

_imageView.frame = CGRectMake(0, 0, size.width, size.height);
_scrollView.contentSize = size;
if (size.height < _scrollView.bounds.size.height) {
    CGFloat offsetY = (_scrollView.bounds.size.height - size.height) * 0.5;
    
    _scrollView.contentInset = UIEdgeInsetsMake(offsetY, 0, offsetY, 0);
}}

至此图片的正常显示及位置的显示都已经可正常实现,至于其他一些功能可根据需要自己添加,此处只简单介绍双击缩放功能;

UIScrollView缩放

要让滚动视图可以缩放需要时设置minimumZoomScalemaximumZoomScale两个属性的值(默认为1),还需要在滚动视图的代理中实现viewForZoomingInScrollView:方法

    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _imageView;
        
    }

该方法返回滚动视图中哪个子视图是可以缩放的,如果滚动视图有多个子视图,但是通常我们需要缩放整个滚动视图的内容,那么将多个视图放在一个视图即可,在将这个视图成为滚动视图的子视图。

滚动视图通过对捏合手势的响应进行缩放,如果缩放超出了我们设置的限制,当手势结束时,尺寸退回到我们设置的限制。如果想要严格的限制缩放不超过我们设置的限制,将bouncesZoom设置为NO即可。

至此图片查看的正常显示 及适当的捏合缩放已经实现;

在某种情况下,比如我们需双击要进行缩放的时候,就要用代码进行缩放,使用下面两个方法:

- (void)setZoomScale:(CGFloat)scale animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated NS_AVAILABLE_IOS(3_0);
  • setZoomScale:animated: 根据比例缩放
  • zoomToRect:animated: 给定矩形的大小进行缩放

在图片查看中常用的是zoomToRect:animated:

- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated,把从scrollView里截取的矩形区域缩放到整个scrollView当前可视的frame里面。如果截取的区域大于scrollView的frame时,图片缩小,
如果截取区域小于frame,会看到图片放大。一般情况下rect需要自己计算出来。即要把用户点击坐标附近的区域内容在scrollViewl里进行缩放
例如:若要把scrollView原来坐标点为(50,60)的点的周围内容在scrollView里放大一倍,可以求出需要从scrollView里截取图片的frame,当然主要是求截取图片坐标原点,内容放大一倍,那么截取图片的大小宽度肯定是
scrollView的frame大小一半。如下列方法:

/** 计算点击点所在区域frame */
- (CGRect)getRectWithScale:(CGFloat)scale andCenter:(CGPoint)center{
CGRect newRect = CGRectZero;
newRect.size.width =  _scrollView.frame.size.width/scale;
newRect.size.height = _scrollView.frame.size.height/scale;
newRect.origin.x = center.x - newRect.size.width * 0.5;
newRect.origin.y = center.y - newRect.size.height * 0.5;

return newRect;
}

在双击手势中作如下处理即可:

- (void)doubleTap:(UITapGestureRecognizer *)recognizer {
if (_scrollView.zoomScale > 1.0) {
    [_scrollView setZoomScale:1.0 animated:YES];
} else {
    CGPoint touchPoint = [recognizer locationInView:_imageView];
    CGFloat scale = _scrollView.maximumZoomScale;
    CGRect newRect = [self getRectWithScale:scale andCenter:touchPoint];
    [_scrollView zoomToRect:newRect animated:YES];
}
}

缩放逻辑视图(画图技术有限,勿喷)

缩放视图逻辑
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容