Incorporating Gesture Support
You can add greater interactivity to your collection views through the use of gesture recognizers. 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:
- You want to trigger changes to the collection view’s layout information.
- You want to manipulate cells and views directly.
You should always attach your gesture recognizers to the collection view itself—not to a specific cell or view. The UICollectionView class is a descendant of UIScrollView, so 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.
你可以通过使用手势为你的集合视图添加更大的交互性。将手势识别器添加到集合视图,并使用它来触发手势发生时的操作(action)。对于集合视图,你可能想要实现两种类型的操作:
- 你想要触发集合视图布局信息的更改。
- 你想直接操纵cells和视图。
你应该始终将你的手势识别器附加到集合视图本身 - 而不是特定的cell或视图。UICollectionView类是UIScrollView的子类,所以附加到集合视图的手势不太可能妨碍其他必须要跟踪的手势。另外,由于集合视图可以访问数据源和布局对象,因此你仍然可以访问需要操作cell和视图所有的信息。
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.
- Create the gesture recognizer.
- Attach the gesture recognizer to the collection view.
- Use the handler method of the gesture recognizer to update the layout parameters and invalidate the layout object.
You create a gesture recognizer using 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’s addGestureRecognizer: method to attach it to the view. Most of the actual work happens in the action method you specify at initialization time.
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.
手势识别器提供了一种动态修改布局参数的简单方法。例如,你可以使用捏合手势识别器来更改自定义布局中项目之间的间距。配置这种手势识别器的过程相对简单。
- 创建手势识别器。
- 将手势识别器附加到集合视图。
- 使用手势识别器的处理程序方法来更新布局参数并使布局对象无效。
使用与所有对象相同的alloc/init过程创建手势识别器。在初始化期间,你可以指定触发手势时调用的目标对象和操作方法(target object and action method)。然后调用集合视图的addGestureRecognizer:方法将其附加到视图。大部分实际工作都是在初始化时指定的操作方法(action method)中进行的。
清单4-1显示了一个由连接到集合视图的捏合手势识别器调用的action方法的示例。在此示例中,夹点数据用于更改自定义布局中cells之间的距离。布局对象实现自定义updateSpreadDistance方法,该方法验证新的距离值并将其存储以供以后的布局过程中使用。操作方法action method)会使布局无效,并强制它根据新值更新items的位置
Listing 4-1 Using a gesture recognizer to change layout values
- (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.
Working with Default Gesture Behaviors
The UICollectionView class listens for single taps to initiate its delegate methods for highlighting and selecting. 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 values the collection view already uses. For example, you might configure a tap gesture recognizer to respond only to double-taps.
Listing 4-2 shows how you might make the collection view respond to your gesture instead of listening for cell selection/highlighting. Because the collection view does not use a gesture recognizer to initiate its delegate methods, your custom gesture recognizer gets priority over the default selection listeners by delaying the registering of other touch events by setting the delaysTouchesBegan
property of your gesture recognizer to YES or cancelling touch events by setting the cancelsTouchesInView
property of your gesture recognizer to YES. Whenever a tap is registered, it will first check to see if your gesture recognizer should have priority or not. If the input is not valid for your gesture recognizer, then the delegate methods will be called as normal.
UICollectionView类监听单个轻拍以启动高亮和选中的delegate方法。如果要将自定义轻击或长按手势添加到集合视图,请将手势识别器的值配置为与集合视图已使用的值不同。例如,你可以配置一个轻击手势识别器来仅响应双击。
清单4-2显示了如何使集合视图响应你的手势,而不是侦听单元格选中/高亮。因为集合视图不使用手势识别器来启动其delegate方法,所以通过延迟其他触摸事件的注册(将delaysTouchesBegan属性设置为YES或取消触摸事件-cancelsTouchesInView属性设为YES),你的自定义手势识别器优先于默认的selection listeners(选择侦听器)。每次轻敲注册时,都会首先检查你的手势识别器是否应该有优先权。如果输入对你的手势识别器无效,那么delegate方法将被正常调用
Listing 4-2 Prioritizing your gesture recognizer
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
tapGesture.delaysTouchesBegan = YES;
tapGesture.numberOfTapsRequired = 2;
[self.collectionView addGestureRecognizer:tapGesture];
Manipulating Cells and Views
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.
One type of manipulation that requires a custom gesture recognizer to move 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.
For more information about creating custom gesture recognizers, see Event Handling Guide for iOS.
如何使用手势识别器来操作cell和视图取决于你计划进行的操作类型。简单的插入和删除操作可以在标准手势识别器的动作方法中执行。但是,如果你计划更复杂的操作,则可能需要你自己定义一个自定义手势识别器来跟踪触摸事件。
一种类型的操作,需要一个自定义手势识别器来将你的集合视图中的cell从一个位置移动到另一个位置。移动cell最直接的方法是从集合视图中(暂时)删除它,使用手势识别器拖动该cell的视觉表示,然后在触摸事件结束时将单元格插入新位置。所有这些都需要你自己管理触摸事件,与布局对象紧密合作以确定新的插入位置,操作数据源更改,然后将该项目插入新位置。
有关创建自定义手势识别器的更多信息,请参阅《Event Handling Guide for iOS》。
网友评论