Recently encountered in the project about the iOS gesture problem, the first requirement is described as follows:" in a collectionview, it is required to long press different cells, to produce a cell snapshot, At this point you can drag and drop the snapshot for subsequent operations (such as dragging to a location on the view to start an event). The requirement itself is not complex, but requires only one cell response long press gesture at a time, and it is not allowed to have two or more cell response long press gestures at a time.
We know that Uigesturerecognizer has many callbacks and methods that are compatible with multiple gestures on the same view , and there are many tutorials on the web, such as:
Http://coder.aqualuna.me/2011/07/uigesturerecognizer.html
There is also this very comprehensive flow-through tutorial:
http://blog.csdn.net/namehzf/article/details/7424882
But there is no solution to my problem because I am studying the coexistence of gestures on multiple subview , not the coexistence of different gestures on a single view. So ask for your own, solve it yourself. (For this I made a simplified demo to put here Https://github.com/pigpigdaddy/LongPressSingleDemo, for readers to download treatise)
There are two ideas:
1, add a long-press gesture to the CollectionView, and the cell (if any) of this position is obtained by the position point of the gesture on the CollectionView. advantages : Less code, simpler logic. disadvantage : Two cells at the same time, any long press operation is not recognized!
Related code:
1- (void) Longpressaction: (Uilongpressgesturerecognizer *) Ges2 {3 if(Ges.state = =Uigesturerecognizerstatebegan) {4Cgpoint point =[Ges LocationInView:self.collectionView];5Nsindexpath *indexpath =[Self.collectionview Indexpathforitematpoint:point];6NSLog (@"%@==%d==%d", Indexpath, Indexpath.section, indexpath.row);7 }8}
Since the idea of 1 cannot achieve my needs, then I will not discuss this, the demo code is not reflected, but this idea may be applicable to other needs.
2, the long press gesture on the Collectionviewcell, long press response, in the form of delegate callback, the director according to the cell location, cell index and other related attributes uploaded to the upper layer, and then the relevant follow-up operations. Advantage : You can respond to the long press of one or more cells at the same time. disadvantage : Multiple cells respond at the same time and cannot meet the needs of my project. So, how to solve it? This is the key to this article.
In the Uigesturerecognizer callback, there is one of the most basic:
1 -(BOOL) Gesturerecognizershouldbegin: (Uigesturerecognizer *) gesturerecognizer 2{ 3 return YES;
}
Returns Yes by default. So, if I set this to no after the current cell responds to a long-press event, then the next cell will not respond to the long-press event. In addition, after the current cell's long press is finished, then set this to Yes, and the subsequent cell will be able to respond to its long-press event.
So, I created a singleton, specifically to control the global long-press event, to make a singleton, rather than the cell's upper view to record the long-press state, because considering the commonality between projects, if the future project needs such requirements, you can directly reference the Singleton class.
OK, here is my single-instance interface file:
1 //2 //LongPressControl.h3 //Classroom4 //5 //Created by Pigpigdaddy on 14-3-24.6 //Copyright (c) 2014 Pigpigdaddy. All rights reserved.7 //8 //Some interfaces may have multiple sub-interfaces, which have their own long-press events, if you do not want these to be triggered by events successively9 //This class can be used to controlTen One //2014-04-08 Increase the distinction gesture call A -typedefenum { -Long_press_view_demo =1, the }long_press_view; - - #import<Foundation/Foundation.h> - + @interfaceLongpresscontrol:nsobject - { +Nsmutablearray *_arraylongpressview; A } at - #pragmaMark - #pragmaMark-------------Create a destroy--------------------- - /** Function Name: Shareinfo - * * Function: Create Longpresscontrol Singleton object - * * Function Parameters: in * * Function return value: Urlog Singleton object - **/ to+ (Longpresscontrol *) Shareinfo; + - /** Function Name: Freeinfo the * * Function: Release Longpresscontrol Singleton Object * * * Function Parameters: $ * * Function return value:Panax Notoginseng **/ -+(void) Freeinfo; the + /*! A * TODO: Add long press event the * + * View called by @param view - * $ * @author Pigpigdaddy $ */ -- (void) Addlongpressaction: (Long_press_view) VIEW; - the /*! - * TODO: Delete Long press eventsWuyi * the * View called by @param view - * Wu * @author Pigpigdaddy - */ About- (void) Removelongpressaction: (Long_press_view) VIEW; $ - /*! - * TODO: whether there is a long press event - * A * @param view is the view + * the * @return - * $ * @author Pigpigdaddy the */ the-(BOOL) isexistlongpressaction: (Long_press_view) VIEW; the the @end
Long_press_view this type, which is used to record and distinguish which VIEW is currently in need of such control, such as Long_press_view_demo in the DEMO, which can be added to the type later.
The _arraylongpressview is used to add type types, and if the cell gesture responds, the type of the corresponding view is added in.
Three functions, add type when cell starts gesture, remove type when cell end gesture, and determine if current view has cell being responded to gesture.
In this case, the singleton is like a lock, and once the gesture is entered, it is locked until the gesture is closed.
Take a look at my actual Democell implementation file, how to handle gestures
1- (void) Longpressaction: (Uilongpressgesturerecognizer *) Ges2 {3 Switch(ges.state) {4 Caseuigesturerecognizerstatebegan:{5NSLog (@"%@", [NSString stringWithFormat:@"%d===%d", Self.indexPath.section, Self.indexPath.row]);6 }7 Break;8 Caseuigesturerecognizerstatechanged:{9 Ten } One Break; A Caseuigesturerecognizerstateended:{ - [[Longpresscontrol Shareinfo] removelongpressaction:long_press_view_demo]; - } the Break; - Caseuigesturerecognizerstatecancelled:{ - [[Longpresscontrol Shareinfo] removelongpressaction:long_press_view_demo]; - } + Break; - Caseuigesturerecognizerstatefailed:{ + [[Longpresscontrol Shareinfo] removelongpressaction:long_press_view_demo]; A } at Break; - - default: - Break; - } - } in --(BOOL) Gesturerecognizershouldbegin: (Uigesturerecognizer *) Gesturerecognizer to { + if(Gesturerecognizer! =self.longpressges) { - returnNO; the}Else if([[[Longpresscontrol Shareinfo] Isexistlongpressaction:long_press_view_demo]) { * returnNO; $}Else{Panax Notoginseng [[Longpresscontrol Shareinfo] addlongpressaction:long_press_view_demo]; - returnYES; the } +}
In this way, multiple cells in my CollectionView no longer respond to multiple cell gestures at the same time, and only the first cell responds to the long press gesture . Work well!
Please refer to Demo (here Https://github.com/pigpigdaddy/LongPressSingleDemo)
In addition, I encountered a problem, that is
-(BOOL) Gesturerecognizershouldbegin: (uigesturerecognizer *) Gesturerecognizer function each time it enters, there will be a like " Collectionviewcell's own long-press gesture (_handlegesturerecognizer)"will enter, I refer to the Uicollectionviewcell. h file, which declares the @class Uilongpressgesturerecognizer; but did not find any interface about gestures, it's strange, is it a repertoire of iOS? Do you have any idea what you can do to help explain? Thank!