您的位置:首页 > 产品设计 > UI/UE

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

2015-09-24 00:47 507 查看
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是图片的Height
if (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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: