要實(shí)現(xiàn)下滑關(guān)閉圖片這個(gè)功能,可以將其分解為幾個(gè)需求:
- 向下滑動(dòng)圖片
- 圖片隨著往下滑動(dòng)會(huì)逐漸變小癣猾,往上滑動(dòng)則會(huì)還原至初始大小
- 往下滑動(dòng)背景越來越透明,往上滑動(dòng)則還原至不透明
滑動(dòng)圖片很簡(jiǎn)單烟具,添加一個(gè)拖拽手勢(shì)即可:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(photoPan:)];
pan.delegate = self;
[imageView addGestureRecognizer:pan];
然后就是實(shí)現(xiàn)滑動(dòng)過程中袄膏,圖片縮小放大動(dòng)畫以及背景色變化,實(shí)現(xiàn)代碼如下所示:
-(void)photoPan:(UIPanGestureRecognizer *)panGesture
{
SDBrowserImageView *attchView = (SDBrowserImageView *)panGesture.view;
CGPoint pointTrans = [panGesture translationInView:_scrollView];
CGPoint point = [panGesture locationInView:_scrollView];
NSLog(@"attchView.transform:%@",NSStringFromCGAffineTransform(attchView.transform));
NSLog(@"x:%f , y:%f",point.x,point.y);
if (panGesture.state == UIGestureRecognizerStateBegan)
{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
self.startPoint = point;
}
else if(panGesture.state == UIGestureRecognizerStateChanged)
{
CGFloat deviationY = point.y - _startPoint.y;
CGFloat scaleTrans = 1 - pointTrans.y/SCREEN_HEIGHT;//縮放比例
CGFloat scaleAlpha = (1 - deviationY/SCREEN_HEIGHT) > 0 ? (1 - deviationY/SCREEN_HEIGHT):0.2;//背景色變化比例
self.backgroundColor = [UIColor colorWithWhite:0.1 alpha:scaleAlpha];
if (deviationY > 0)
{
NSLog(@"scaleTrans : %.2f",scaleTrans);
CGAffineTransform trans = CGAffineTransformMakeTranslation(pointTrans.x, pointTrans.y);
CGAffineTransform scale = CGAffineTransformScale(attchView.transform, scaleTrans, scaleTrans);
CGAffineTransform newTransform = CGAffineTransformConcat(trans, scale);
attchView.transform = newTransform;
}
else
{
CGAffineTransform trans = CGAffineTransformTranslate(attchView.transform, pointTrans.x, pointTrans.y);
attchView.transform = trans;
}
}
else if(panGesture.state == UIGestureRecognizerStateEnded)
{
CGFloat deviationY = point.y - _startPoint.y;
if (deviationY >= 60)
{
[self photoPanFinished:attchView];
}
else
{
[UIView animateWithDuration:0.2 animations:^{
attchView.transform = CGAffineTransformIdentity;
}];
}
}
else if(panGesture.state == UIGestureRecognizerStateCancelled)
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
else if(panGesture.state == UIGestureRecognizerStateFailed)
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
}
//增量置為o
[panGesture setTranslation:CGPointZero inView:attchView];
}
translationInView:
是為了獲取每次拖拽間距甫煞,往下為正菇曲,往上為負(fù),往左為負(fù)抚吠,往右為正常潮。
startPoint是初始觸摸點(diǎn),locationInView:
是為了獲取相對(duì)于觸摸view的父視圖的移動(dòng)距離楷力。
CGAffineTransformMakeTranslation 是位移變換喊式。
CGAffineTransformScale 是縮放變換。
CGAffineTransformConcat 組合兩個(gè)動(dòng)畫弥雹。
CGAffineTransformIdentity 是動(dòng)畫初始狀態(tài)垃帅。
每次移動(dòng)一段距離都需要執(zhí)行setTranslation:
方法,將增直量置為0剪勿,否則接下來的移動(dòng)會(huì)疊加之前距離贸诚。
在拖拽距離超過60,且松手后,會(huì)執(zhí)行photoPanFinished:
方法以關(guān)閉圖片酱固。
在查看圖片時(shí)械念,實(shí)現(xiàn)下滑以關(guān)閉圖片過程中,碰到一個(gè)問題:Pan手勢(shì)與UIScrollView自帶的Pan手勢(shì)沖突运悲,只能相應(yīng)下滑關(guān)閉手勢(shì)龄减,不能相應(yīng)左右滑動(dòng)手勢(shì),解決辦法如下:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
CGPoint pos = [pan velocityInView:pan.view];
if (pos.y > 0) {
return YES;
}
}
return NO;
}
其中velocityInView:是用來獲取滑動(dòng)速度的班眯,pos.y > 0 表示速度向下希停,反之向上。
這個(gè)方法還可以解決如下問題:
- 可以使得向下滑動(dòng)圖片時(shí)署隘,scollview不動(dòng)(只需要多加一行禁用scrollview的代碼)
2.使圖片初始不能向上滑動(dòng)宠能,只能向下滑