微信图片浏览效果模仿--如何解决`touch`事件的冲突

目前微信的交互效果是国内顶级的,很多人也都比较熟悉和习惯它的交互,很多公司的应用也会参考它的效果,我们今天就来看下图片浏览的效果如何实现。

大概有三个功能点:

1. 可以左右分页滑动
2. 可以拖动并缩小
3. 可以双击放大某一部分

这里的touch事件就需要三种:

1. 滚动
2. 拖动
3. 点击

技术难题出来了:双击没影响,左右滑动和拖动其实是矛盾的,即用户开始触摸的时候,是没法知道是想拖动,还是想左右滑动的。上升下就是如何解决不同touch事件的冲突?

要做这个判断,我们可根据这条规则:判断用户开始滑动时的方向,向下则认为用户想拖动,向左右则认为其想滑动。

这里有三个思路来实现:

1. 使用scrollView的`Delegate`等来实现功能
2. 继承`UIGestureRecongnizer`类,重写部分的方法。 或者增加其的category,增加部分需要的方法
3. 从底层重写,即重写 `touchBegan` 等方法

这三个思路我都在不同的文章中看到,下面说下我的看法:

scrolView的Delegate

先说结论,这个是实现最简单,但是效果最差的。

很多人可能第一直觉就是在delegate去判断,这也是相对最好实现的.但是其效果是最差的,因为ScrollView的delegate其实是最晚拿到滚动消息的,这就带来了刚开始滑动时候的卡顿。

代码类似于这样,向下滚动则使用拖动

1
2
3
4
5
6
7
8
9
10
11
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
static float scrollNewY = 0;
static float scrollOldY = 0;
scrollNewY = scrollView.contentOffset.y;
if ((scrollView.contentOffset.y < 0 || self.doingPan) && (self.doingZoom == NO))
{
[self doPan:self.mainScrollView.panGestureRecognizer];
}
scrollOldY = scrollNewY;
}

UIGestureRecongnizer

这是相对来讲效果较好,实现也比较方便的方法。

无论是写category还是继承子类,功能都不复杂,而且效果也会比较好。

实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if (!self.isMoving){
UITouch *touch = [touches anyObject];
CGPoint nowPoint = [touch locationInView:self.view];
CGPoint prevPoint = [touch previousLocationInView:self.view];
BOOL isHorzitional = prevPoint.x - nowPoint.x > 5;
BOOL isVertical = nowPoint.y - prevPoint.y > 5;
if (!isHorzitional && isVertical){
self.isMoving = YES;
self.isVerticalDownPan = YES;
} else {
self.isVerticalDownPan = NO;
self.state = UIGestureRecognizerStateFailed;
}
}
[super touchesMoved:touches withEvent:event];
}

我这里使用的是直接重写touchesMoved来判断,也可以使用getureRecongnizer的方法来做。

UITouch

这个方式可以用来处理非常复杂的效果,但是这里不推荐,因为要花费的精力实在太大,如果有选择,尽量使用系统提供的单击、双击、拖动等类来做,没必要重新造轮子。

实现即重写touchesBegan,touchesMoved,touchesEnded,touchesCanceled等方法

githubDemo: lfImageBrowserImitateWechat

其他类似项目参考:

1. https://github.com/JiongXing/PhotoBrowser
 2. https://github.com/MSS0306/MSSBrowse
 3. https://github.com/tianliangyihou/LBPhotoBrowser
 4. https://github.com/QuintGao/GKPhotoBrowser