Incorporating Gesture Support
结合手势支持
You can add greater interactivity to your collection views through the use of gesture recognizers. Like any view, you can add a gesture recognizer to a collection view and use it to trigger actions when those gestures occur. For a collection view, there are two types of actions that you might likely want to implement:
你可以通过使用手势识别给collection 视图添加更大的交互性(interactivity)。跟任何视图一样,你可以给一个collection 视图添加手势识别,当那些手势发生时可以用它来触发各种操作。collection 视图有两种类型的操作是你可能想要实现的,它们是:
-
You want to trigger changes to the collection view’s layout information
- 你想要触发collection 视图的布局信息改变.
-
You want to manipulate cells and views directly.
- 你想要直接操作单元格(cells)和视图.
You should always attach your gesture recognizers to the collection view itself and not to a specific cell or view. The UICollectionView
class is a descendant ofUIScrollView
. Attaching your gesture recognizers to the collection view is less likely to interfere with the other gestures that must be tracked. In addition, because the collection view has access to your data source and your layout object, you still have access to all the information you need to manipulate cells and views appropriately.
你应该总是给collection 视图本身添加(attach)手势识别,而不是给某个特定的cell 或视图。UICollectionView 类是UIScrollView 类的一个子类(descendant). 把手势识别添加到collection 视图不太可能会妨碍其它必须被跟踪(tracked)的各种手势。另外, 因为collection 视图已经访问了你的数据源和布局对象,你还可以访问了你需要相应地(appropriately)操作cells 和视图的所有的信息。
Using a Gesture Recognizer to Modify Layout Information
一、 使用手势识别来修改布局信息
A gesture recognizer offers an easy way to modify layout parameters dynamically. For example, you might use a pinch gesture recognizer to change the spacing between items in a custom layout. The process for configuring such a gesture recognizer is relatively simple:
手势识别给动态修改布局参数提供一条简单的方法。 比如, 你可能使用一个捏合(pinch)手势识别来改变一个自定义布局上数据项之间的距离。配置这样一个手势识别相对比较简单:
-
Create the gesture recognizer.
创建手势识别
-
Attach the gesture recognizer to the collection view.
给collection 视图添加手势识别
-
Use the handler method of the gesture recognizer to update the layout parameters and invalidate the layout object.
使用手势识别的处理方法来更新布局参数以及无效化布局对象。
Creating a gesture recognizer is the same alloc/init process that you use for all objects. During initialization, you specify the target object and action method to call when the gesture is triggered. You then call the collection view’saddGestureRecognizer:
method to attach it to the view. Most of the actual work happens in the action method you specify at initialization time.
创建一个手势识别跟所有对象一样都是alloc/init 过程。 初始化时,你指定目标对象和当手势触发时要调用的操作方法。然后调用collection 视图的addGestureRecognizer: 方法来把它添加到视图。 大部分的实际工作发生在初始化时你指定的操作方法中。
Listing 4-1 shows an example of an action method that is called by a pinch gesture recognizer attached to a collection view. In this example, the pinch data is used to change the distance between cells in a custom layout. The layout object implements the custom updateSpreadDistance
method, which validates the new distance value and stores it for use during the layout process later. The action method then invalidates the layout and forces it to update the position of items based on the new value.
列表4-1 显示了一个操作方法例子,该方法由一个collection 视图中的捏合手势识别(pinch gesture recognizer)调用。 在该例子中, 捏合(pinch)数据被用于改变一个自定义布局上cells之间的距离。 该布局对象实现了自定义 updateSpreadDistance 方法,它激活新的距离值并保存它以便在以后的布局过程中使用。操作方法然后无效化布局并强制布局根据新值更新数据项的位置。
Using a gesture recognizer to change layout values
列表4-1 使用一个手势识别来改变布局变量值
- (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]; |
} |
For more information about creating gesture recognizers and attaching them to views, see Event Handling Guide for iOS.
关于创建手势识别和给视图添加手势识别的更多信息,请看Event Handling Guide for iOS.
Working with the Default Gesture Recognizers
二、用默认手势识别工作
The parent class of UICollectionView
class installs a default tap gesture recognizer and a default long-press gesture recognizer to handle scrolling interactions. You should never try to reconfigure these default gesture recognizers or replace them with your own versions. If you want to add custom tap or long-press gestures to a collection view, configure the values of your gesture recognizer to be different than the default ones that are already installed. For example, you might configure a tap gesture recognizer to respond only to double-taps. You must then link your custom gesture recognizer to the default versions using therequireGestureRecognizerToFail:
method. That method causes the default gesture recognizer to fire only when your gesture recognizer decides not to fire.
UICollectionView 类的父类带有一个默认的叩击(tap)手势识别和一个默认的长按(long-press)手势识别来处理滚动交互。 你决不能试着重新识别这些默认手势识别,或用你自己的版本来替换它们。 如果你想给collection 视图添加自定义叩击或长按手势,给你的手势识别设置一个跟默认手势不一样的值。比如,你可能设置一个叩击(tap)手势来只响应双叩击(double-taps)。 然后你必须用requireGestureRecognizerToFail: 方法来把你自定义的手势识别连接到默认版本。 该方法导致默认手势识别只在你的手势识别决定响应的时候才响应。
Listing 4-2 shows how you might link a custom tap gesture recognizer to the default recognizer associated with a collection view. In this case, the owning view controller adds the gesture recognizer to the collection view at load time. After creating the custom gesture recognizer, the code iterates through the collection view’s default set of gesture recognizers looking for one of the same type. It then links the default gesture recognizer to the custom one that was just created. Finally, the view controller adds the gesture recognizer to the collection view. It adds the gesture recognizer last to avoid encountering it during the for
loop.
列表4-2 显示了你可能如何把一个自定义叩击手势识别连接到collection 视图中的默认手势识别上。 在这种情况下,所属视图控制器在加载时把手势识别添加到collection 视图。 创建完自定义手势识别后,代码迭代地在collection 视图的默认手势识别集合中搜索一个相同的类型。 然后把它连接到该默认手势识别上。 最后,视图控制器把手势识别添加到collection 视图上。 它在最后添加手势识别是为了避免在循环时遇见t(encountering)。
Linking a default gesture recognizer to a custom gesture recognizer
列表4-2 把一个默认手势识别连接到一个自定义手势识别上
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; |
NSArray* recognizers = [self.collectionView gestureRecognizers]; |
// Make the default gesture recognizer wait until the custom one fails. |
for (UIGestureRecognizer* aRecognizer in recognizers) { |
if ([aRecognizer isKindOfClass:[UITapGestureRecognizer class]]) |
[aRecognizer requireGestureRecognizerToFail:tapGesture]; |
} |
// Now add the gesture recognizer to the collection view. |
tapGesture.numberOfTapsRequired = 2; |
[self.collectionView addGestureRecognizer:tapGesture]; |
Manipulating Cells and Views
三、操作Cells 和视图
How you use a gesture recognizer to manipulate cells and views depends on the types of manipulations you plan to make. Simple insertions and deletions can be performed inside the action method of a standard gesture recognizer. But if you plan more complex manipulations, you probably need to define a custom gesture recognizer to track the touch events yourself.
如何使用一个手势识别来操作cells 和视图依赖于你计划做的操作的类型。 简单的插入和删除可以在一个标准手势识别的操作方法内执行。 但是如果你计划更复杂的操作,你可能需要定义一个自定义手势识别来跟踪你自己的触摸事件。
One type of manipulation that requires a custom gesture recognizer is moving a cell in your collection view from one location to another. The most straightforward way to move a cell is to delete it (temporarily) from the collection view, use the gesture recognizer to drag around a visual representation of that cell, and then insert the cell at its new location when the touch events end. All of this requires managing the touch events yourself, working closely with the layout object to determine the new insertion location, manipulating the data source changes, and then inserting the item at the new location.
一种要求一个自定义手势识别的操作类型是把collection视图中的一个cell 从一个位置移到另一个位置。 把一个cell 从collection 视图上(暂时)删除的最直接方法是使用手势识别来拖动该cell拖到一个可视化替代,然后当触摸事件结束时把该cell插入它的新位置。 所有这些操作都要求管理自身的触摸事件,和布局对象紧密工作来决定新的插入位置,操作数据源的改变,然后把数据线插入新位置。
For more information about creating custom gesture recognizers, see Event Handling Guide for iOS.
关于创建自定义手势识别的更多信息,请看 Event Handling Guide for iOS.