iOS图片浏览器控件 放大,缩小,UIScrollView

GitHub地址 https://github.com/JerryWanXuJie/XJAlbum

图片浏览器主要通过 UIScrollView 实现  在一个大的ScollView里面套 n个ScollView

UIScrollView里主要是有两个属性,contentSize和contentoffset , contentSize 是设定UIScrollView的可交互的大小,contentoffset偏移量

设置第一层 UIScollView 主要是设置 contentSize 和 contentoffset , contentSize 是根据图片的个数来设定,contentoffset根据当前图片编号设定    wholeScoll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, myScreenWidth, myScreenHeight)];
    wholeScoll.contentOffset = CGPointMake(wholeScoll.frame.size.width*mcurpage, 0);   wholeScoll.contentSize = CGSizeMake(myScreenWidth*mImgLocationArr.count, myScreenHeight);

// 主要代码是通过for 循环添加第二层UIScrollView

  for (int i = 0; i<mImgLocationArr.count; i++) {

//设置 imageview

  UIImageView * imgview = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, myScreenWidth, myScreenHeight)];

  imgview.contentMode = UIViewContentModeScaleAspectFit;

//设置 scrollview

  UIScrollView * singleview = [[UIScrollView alloc]initWithFrame:CGRectMake(myScreenWidth*i,0,myScreenWidth, myScreenHeight)];

  [wholeScoll addSubview:singleview];

  [singleview addSubview:imgview];

// 添加手势

  [self addGestureRecognizer];

}

图片浏览器中图片可以左右滑动,可以双击放大,可以手势捏合放大缩小

图片浏览器中主要有三种手势分别是单击 singleTap 双击doubleTap 捏合 pinchGesture 和UIScrollView自带的滑动手势

singleTap 手势主要是返回上一页面,如果触发singleTap的时候图片已经放大,那么先将图片初始化大小和坐标

因为singleTap 和 doubleTap 是属于同一手势类,会产生手势冲突,所以需要

[singleTap requireGestureRecognizerToFail:doubleTap];在执行doubleTap的时候注销掉singleTap

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~然后高潮来了~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我是可爱的分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

最主要的操作是 doubleTap 和pinchGesture,这也是花了我最多时间的两个问题

首先讲一下doubleTap的思想,大家注意观察微信的图片浏览器,doubleTap在执行的时候会得到一个在View的点   CGPoint tapPoint = [doubletap locationInView:doubletap.view];

然后双击后,放大UIImageView,然后通过设定contentoffset偏移量将 tapPoint 移到屏幕最中间,这是双击的点包含在图片里的情况,另外一种情况,是双击的点在图片外,然后点在图片外又有 左上,右上,左下,右下四种情况。分别将图片放大然后,图片左上,右上,左下,右下四个方向贴边显示

然后根据tapPoint的x,y判断四种不同的情况

tapX,tapY是tapPoint的x,y  imgY是图片的y值,imgHeight是图片的Heightif (tapY<imgY) {
        //上面
        pointType = XJAlbumOutImgViewPointLeftUp;
        if (tapX>myScreenWidth/2) {
            pointType = XJAlbumOutImgViewPointRightUp;
        }
        isOutImgView = YES;
    }
    else if(tapY>imgY+imgHeight)
    {
        //下面
        pointType = XJAlbumOutImgViewPointLeftDown;
        if (tapX>myScreenWidth/2) {
            pointType = XJAlbumOutImgViewPointRightDown;
        }
        isOutImgView = YES;
    }

if (isOutImgView) {
                //如果点击的是在图片外面
                NSLog(@"isout");

                switch (pointType) {
                    case XJAlbumOutImgViewPointLeftUp:
                    {
                        singleScrollView.contentOffset = CGPointMake(0, 0);
                    }
                        break;
                    case XJAlbumOutImgViewPointLeftDown:
                    {
                        singleScrollView.contentOffset = CGPointMake(0, imgview.frame.size.height - myScreenHeight);
                    }
                        break;
                    case XJAlbumOutImgViewPointRightDown:
                    {
                        singleScrollView.contentOffset = CGPointMake(imgview.frame.size.width - myScreenWidth, imgview.frame.size.height - myScreenHeight);
                    }
                        break;
                    case XJAlbumOutImgViewPointRightUp:
                    {
                        singleScrollView.contentOffset = CGPointMake(imgview.frame.size.width - myScreenWidth, 0);
                    }
                        break;
                    default:
                    break;
                }
            }
            else
            {
                //将双击的点设置到屏幕的中心   先计算出点距图片边缘的距离,然后根据比例求出offsetX;       imgX,imgY 分别是图片的 x,y 坐标值
                CGFloat offsetX = (tapX-imgX)*maxScale - myScreenWidth/2;
                CGFloat offsetY = (tapY-imgY)*maxScale - myScreenHeight/2;
                //如果超出最大范围,则设置边界值
                offsetY = offsetY<0?0:offsetY;
                offsetY = offsetY>imgview.frame.size.height-myScreenHeight?imgview.frame.size.height-myScreenHeight:offsetY;
                offsetX = offsetX<0?0:offsetX;
                offsetX = offsetX>imgview.frame.size.width - myScreenWidth?imgview.frame.size.width - myScreenWidth:offsetX;
                singleScrollView.contentOffset = CGPointMake(offsetX,offsetY);
            }
            isBigger = YES;

然后就是捏合手势,捏合手势 主要的两点是 实时的根据放大的比例来改变 UIimageView的size , UIScrollView的contentSize,contentoffset

捏合手势 pinchGesture的思想是 获取手势开始时,两点的中心点,然后计算出 该中心点在屏幕中的相对位置 , 在手势变化的时候,保持这个相对位置不改变。

// 变量offsetPinchX 是 scrollview 的 contentoffset.x   xInScreen 是 中心点在屏幕的相对位置,因为手势获取的点是相对手势所在View上的相对位置,所以要减去 scrollview 的 x 偏移量

if (pinchGes.state == UIGestureRecognizerStateBegan) {

oldFirstPoint = [pinchGes locationOfTouch:0 inView:pinchGes.view];

oldSecondPoint = [pinchGes locationOfTouch:1 inView:pinchGes.view];

oldLength = [self caculateLengthBetweenP1:oldFirstPoint P2:oldSecondPoint];

//计算出初始中心点

centrePoint = CGPointMake((oldFirstPoint.x+oldSecondPoint.x)/2,(oldSecondPoint.y+oldFirstPoint.y)/2);

xInScreen = centrePoint.x - offsetPinchX;

}

// minSize 是 初始的size   newSize 通过计算 两个点之间的值的比例来获得

biggerScale = newLength/oldLength;

newSize = CGSizeMake(oldSize.width*biggerScale,oldSize.height*biggerScale);

CGFloat newScale = newSize.width / minSize.width;

    // 算出 在屏幕的点

    if (newSize.width < maxSize.width && newScale>1) {
        offsetPinchX = xInScreen * (newScale - 1);
    }
    if (offsetPinchX<0) {
        offsetPinchX = 0;
    }
    if (offsetPinchX>(newSize.width - myScreenWidth)) {
        offsetPinchX = newSize.width - myScreenWidth;
    }
    NSLog(@"%f ------ %f ------%f",offsetPinchX,centrePoint.x,newScale);

    if (newSize.width == maxSize.width) {

    }
    else
    {
        singleScroll.contentOffset = CGPointMake(offsetPinchX, 0);
    }
时间: 2024-10-10 09:31:59

iOS图片浏览器控件 放大,缩小,UIScrollView的相关文章

HTML5:使用Canvas和Input range控件放大缩小图片

引自:http://blog.csdn.net/ClementAD/article/details/48938261 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>图片缩放</title> </head> <body style="background: black;"> <canvas id

IOS UIWebView(浏览器控件)

什么是UIWebViewUIWebView是iOS内置的浏览器控件系统自带的Safari浏览器就是通过UIWebView实现的 UIWebView不但能加载远程的网页资源,还能加载绝大部分的常见文件html\htmpdf.doc.ppt.txtmp4- - UIWebView常用的加载资源的方法- (void)loadRequest:(NSURLRequest *)request;    常用属性和方法 重新加载(刷新) - (void)reload; 停止加载 - (void)stopLoad

Android开发技巧——定制仿微信图片裁剪控件

拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动和放大的是图片,裁剪框不动. 裁剪框外的内容要有半透明黑色遮罩. 裁剪框下面要显示一行提示文字(这点我至今还是持保留意见的). 在Android中,裁剪图片的控件库还是挺多的,特别是github上比较流行的几个,都已经进化到比较稳定的阶段,但比较遗憾的是它们的裁剪过程是拖动或缩放裁剪框,于是只好自己

UIWebView浏览器控件常用属性与方法汇总

一.什么是UIWebView UIWebView是iOS内置的浏览器控件 系统自带的Safari浏览器就是通过UIWebView实现的 二.UIWebView常用属性和方法 UIWebView常用的加载资源的方法 - (void)loadRequest:(NSURLRequest *)request; @property(nonatomic) UIDataDetectorTypes dataDetectorTypes; // 需要进行检测的数据类型 @property(nonatomic,rea

Essential HTMLUI 浏览器控件介绍及下载

Essential HTMLUIfor Windows Forms是一款WinForm控件用于呈现HTML,功能很像一个Web浏览器,支持各种各样的HTML标签,可以显示丰富的HTML文档,支持导出和打印. 具体功能: HTMLUI是一款完全与浏览器独立的控件,支持以URL的形式打开HTML 支持从用户驱动器路里加载任何HTML页面 支持使用图片代替文本用于连接到其他文件 支持以流的形式加载HTML文档 支持各种各样的HTML标签,格式化相关的标签 支持外部的.内在的.内嵌的样式,支持在运行时添

无比迅速敏捷地开发IOS超精美控件

目录 前言 设计 编码 PaintCode 前言 自从人生第一篇博客<IOS中的预编译指令的初步探究>问世以来 浏览量竟然达到了360多,(路过的大神勿笑!)这些浏览量使我兴奋异常但又令我黯然神伤,为何我会眼里常含泪水?因为国人伸手党达90%!!!区区只有可怜的三个评论,可怜的三个评论~ 没有鼓励~ 没有鲜花~ 也没有谩骂~ 但是我不哭 因为贱人会笑!我深信: 一日伸手党,bug终身随! 好久没打篮球了,“教练,我想打篮球”. 这次的东西标题为<无比迅速敏捷地开发IOS超精美控件>

前端心得---仿IOS拾取器控件(转轮控件)

希望做一个类似IOS拾取器的控件,在IOS上该控件的效果是这样的:,我也把该效果称之为为轮子效果. 要实现这个效果,能够用到的技术点非常简单,无非是transform的translate3d和rotate,不过要想很好的实现,还要建立一个精确的数学模型,来解决如何[摆放]的问题.特别是这个效果不是静态的,需要满足鼠标滑动的时,这个轮子要转起来,这就需要仔细思索了.当然,在最开始重点还是要搞清楚自变量是什么.因变量是什么.它们之间的关系是什么以及该需求的一些性质.找到了好的性质,可以减轻工作量,并

UIWebView --- 内置的浏览器控件 加载网页

描述:UIWebVIew 是IOS一个常见的控件,属内置的浏览器控件,可以用来加载网页,或是打开文件等等. 方法一: 代码实现:(运行程序时,直接显示链接的内容) #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSURL * url=[NSURL URLWithSt

IOS UIStepper(步进控件)使用总结

IOS中步进控件的简单使用 初始化控件 UIStepper * step = [[UIStepper alloc]initWithFrame:CGRectMake(100, 100, 100, 100)]; 设置控制器值是否连续触发变化 @property(nonatomic,getter=isContinuous) BOOL continuous; 若设置为YES,则长按会连续触发变化,若设置为NO,只有在按击结束后,才会触发. 设置长按是否一直触发变化 @property(nonatomic