你可以给collectionView添加手势来提高collectionView的可交互性. 给collectionView添加某种手势, 当用触发该手势时, 会触发collectionView的一个动作. 对于collectionView来说这里有两类动作需要绑定一个手势:
- 你想触发一个collectionView的layout更新动作
- 你想直接操作cell或者view
你应该将手势添加到collectionView而不是某个特定的cell或view. 因为UICollectionView是UIScrollView
的子类, 因此将一个手势添加到collectionView上会减少对其他手势的干扰. 另外, 因为collectionView可以访问DataSource和layout对象, 所以当你给collectionView加上手势时, 你就能获取cell和view的各种信息.
使用手势来修改layout信息
手势提供了一种修改layout对象的便捷方式. 举个例子, 你可能会使用pinch手势来修改item的间距(在自定义布局情况下). 其步骤比较简单, 如下:
- 创建一个手势
- 将创建好的手势添加到collectionView中
- 在手势的Handler方法中做你想要的操作, 比如更新layout的属性, 更新layout对象
创建手势使用常规方法就行(alloc/init), 使用addGestureRecognizer:
方法将手势添加到collectionView中, 设置手势的target, 将action方法实现好(主要部分).
代码清单4-1展示了pinch手势的action, 在action方法中修改自定义的layout, 然后通知系统更新layout对象. 其中的updateSpreadDistance
方法是用来修改layout的某些参数的, 最后调用layout对象的invalidateLayout
方法,通知系统更新collectionView的layout.
代码清单4-1 使用手势来更新layout
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender {
if ([sender numberOfTouches] != 2)
return;
// Get the pinch points.
CGPoint p1 = [sender locationOfTouch:0 inView:[self collectionView]];
CGPoint p2 = [sender locationOfTouch:1 inView:[self collectionView]];
// Compute the new spread distance.
CGFloat xd = p1.x - p2.x;
CGFloat yd = p1.y - p2.y;
CGFloat distance = sqrt(xd*xd + yd*yd);
// Update the custom layout parameter and invalidate.
MyCustomLayout* myLayout = (MyCustomLayout*)[[self collectionView] collectionViewLayout];
[myLayout updateSpreadDistance:distance];
[myLayout invalidateLayout];
}
想知道更多关于手势创建/添加到view的知识, 请看Event Handling Guide for iOS.
collectionView自带手势
-
UICollectionView
能够监听单击手势来触发delegate的高亮/选中方法. 如果你自定义的一个tap或者长按手势添加到collectionView中, 你要注意将自定义的手势和自带的区分开来, 你自定义手势的gesture recognizer对象的某些值需要区别设置, 比如, 你自定义tap手势的只响应双击(double-taps) - 代码清单4-2展示了用自定义的手势替换自带手势(highlight/selection). 你可以将自定义手势的
delaysTouchesBegan
设置为YES, 这样会使自定义手势优先自带手势被处理, 也可以设置cancelsTouchesInView
为YES来排他手势.
代码清单4-2 提高自定义手势的优先级
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
tapGesture.delaysTouchesBegan = YES;
tapGesture.numberOfTapsRequired = 2;
[self.collectionView addGestureRecognizer:tapGesture];
直接操作Cells和Views
如何使用手势来操作cell和view, 取决于你打算做何种操作. 简单的插入/删除操作, 可以使用标准的手势来处理. 但是要做一些复杂的操作时, 需要定义自己的手势, 按照touch事件来处理.
这里有一种操作需要用到自定义手势, 这种操作是:你将一个cell从一个位置移动另外一个位置. 最直接的方式是先cell从初始位置删除, 使用手势拖动删除的cell, 再将该cell插入的目的位置. 该过程需要用到touch事件, layout对象和DataSource.