I can not understand why I have to set
longGesture.minimumPressDuration = 0.3;
longGesture.delaysTouchesBegan = true;
Before the action is being fired, do you know why?
longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
longGesture.minimumPressDuration = 0.3;
longGesture.delaysTouchesBegan = true;
[self.collectionView addGestureRecognizer:longGesture];
Try this code. You don't have to set this longGesture.minimumPressDuration = 0.3
- (void)viewDidLoad
{
UILongPressGestureRecognizer *lpgr
= [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.delegate = self;
lpgr.delaysTouchesBegan = YES;
[self.collectionView addGestureRecognizer:lpgr];
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded) {
return;
}
CGPoint p = [gestureRecognizer locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:p];
if (indexPath == nil){
NSLog(#"couldn't find index path");
} else {
// get the cell at indexPath (the one you long pressed)
UICollectionViewCell* cell =
[self.collectionView cellForItemAtIndexPath:indexPath];
// do stuff with the cell`enter code here`
}
}
Related
I have collectionView in my app. I have a requirement that I should be able to both double & single tap on cells to perform diffrent operations. To make it possible both double & single tap gesture on the collectionView I have added both the gesture on collection view & got the location by below code.
-(void)handleSingleTap:(UITapGestureRecognizer *)gestureRecognizer
{
if([arr_userAlbums count]>0)
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
{
return;
}
p = [gestureRecognizer locationInView:self.collection_view];
NSIndexPath *indexPath = [self.collection_view indexPathForItemAtPoint:p];
celltTapped_index_path=indexPath;
}
}
-(void)handleDoubleTap:(UITapGestureRecognizer *)gestureRecognizer
{
if([arr_userAlbums count]>0)
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
{
return;
}
p = [gestureRecognizer locationInView:self.collection_view];
NSIndexPath *indexPath = [self.collection_view indexPathForItemAtPoint:p];
celltTapped_index_path=indexPath;
}
}
But in this case the whole screen even where cells are not visible it is accepting the double tap & single tap. I want to detect single & double tap only on cells not the whole collection view.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cvCell";
customCell *cell = (customCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.img_Collection.image = [imgArray objectAtIndex:indexPath.row];
cell.lbl_Collection.text = [lblArray objectAtIndex:indexPath.row];
cell.tag = indexPath.row;
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
singleTap.numberOfTapsRequired = 1;
singleTap.delaysTouchesEnded = YES;
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
doubleTap.numberOfTapsRequired = 2;
[singleTap requireGestureRecognizerToFail:doubleTap];
[cell addGestureRecognizer:singleTap];
[cell addGestureRecognizer:doubleTap];
return cell;
}
-(void)handleSingleTap:(UIGestureRecognizer *)recognizer
{
NSLog(#"The single tap happened for %ld th index",recognizer.view.tag);
}
-(void)handleDoubleTap:(UIGestureRecognizer *)recognizer
{
NSLog(#"The Double tap happened for %ld th index",recognizer.view.tag);
}
you can get tapped View by using hitTest Method like this
UIView *tappedView = [self hitTest:yourLocation forEvents:nil];
This will return you the view which is tapped
Check this with if condition like this
if(tappedView == Imageview)
{
// do this
}
else if(tappedView == CollectionViewCell)
{
// do this
}
I have a UICollectionView that I populate from my Image Library.
I want to be able to delete a cell from the collection by using a UILongPressGestureRecognizer on the cell. The UILongPressGestureRecognizer is working.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected cell = %ld",(long)indexPath.item);
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(activateDeletionMode:)];
longPress.delegate = self;
[collectionView addGestureRecognizer:longPress];
}
- (void)activateDeletionMode:(UILongPressGestureRecognizer *)gr
{
if (gr.state == UIGestureRecognizerStateBegan)
{
NSLog(#"delete mode");
}
}
In your case try this
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected cell = %ld",(long)indexPath.item);
UILongPressGestureRecognizer * longPres
= [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(activateDeletionMode:)];
longPres.minimumPressDuration = .5; //seconds
longPres.delegate = self;
[self.collectionView addGestureRecognizer: longPres];
}
- (void)activateDeletionMode:(UILongPressGestureRecognizer *)gr
{
if (gr.state == UIGestureRecognizerStateBegan)
{
NSLog(#"delete mode");
}
}
in other case you can try this
//add long press gesture to collectionView
UILongPressGestureRecognizer *longpress
= [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongpressMethod:)];
longpress.minimumPressDuration = .5; //seconds
longpress.delegate = self;
[self.collectionView addGestureRecognizer: longpress];
}
then handle the action
-(void) handleLongpressMethod:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded) {
return;
}
CGPoint pt = [gestureRecognizer locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:pt];
if (indexPath == nil){
NSLog(#"couldn't find index path");
} else {
// get the cell at indexPath (the one you long pressed)
UICollectionViewCell* cell =
[self.collectionView cellForItemAtIndexPath:indexPath];
// work with the cell
}
delete
[self.youritemarray removeObjectAtIndex:indexPathh];
[collectionView reloadData];
I used the code below to get the location of the cell when touched.
However, when the UICollectionView.bounds.size.width > 320, or > 640, the "origin.x" returned often > 320, for example, 657, 469. Cause there are some images inside cells. So when I touched the cell on the second page. The value X returned may be 368.0 or other values.
I just need to get the value X in the current view.(320 * 480).
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
- (void)viewDidLoad
{
// attach long press gesture to collectionView
UILongPressGestureRecognizer *lpgr
= [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = .5; //seconds
lpgr.delegate = self;
[self.collectionView addGestureRecognizer:lpgr];
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded) {
return;
}
CGPoint p = [gestureRecognizer locationInView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:p];
if (indexPath == nil){
NSLog(#"couldn't find index path");
} else {
// get the cell at indexPath (the one you long pressed)
UICollectionViewCell* cell =
[self.collectionView cellForItemAtIndexPath:indexPath];
// do stuff with the cell
}
}
If I understand your question correctly, your collection view may have multiple pages horizontally. Assuming these pages are frame-width, you could do this:
int xVal = (int)p.x % (int)self.view.frame.size.width;
Keep in mind that you will lose decimal precision.
I have UITableView to display some list. Implemented UILongPressGestureRecognizer to get calls and on this I want to display menu for delete, upload, etc actions.
Following is implementation
// Registering for long press event
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
lpgr.delegate = self;
[self.myTable addGestureRecognizer:lpgr];
On Long Press My control comes to function
- (IBAction)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan)
{
CGPoint p = [gestureRecognizer locationInView:self.playbackTable];
NSIndexPath *indexPath = [self.playbackTable indexPathForRowAtPoint:p];
if (indexPath == nil)
{
NSLog(#"long press on table view but not on a row");
}
else
{
NSLog(#"long press on table view at section %d row %d", indexPath.section, indexPath.row);
CGPoint p = [gestureRecognizer locationInView: self.myTable];
NSIndexPath *indexPath = [self.myTable indexPathForRowAtPoint:p];
if (indexPath != nil)
{
if([self becomeFirstResponder])
{
UIMenuItem *delete = [[UIMenuItem alloc] initWithTitle:#"Delete" action:#selector(deleteFileListItem:)];
menu = [UIMenuController sharedMenuController];
[menu setMenuItems:[NSArray arrayWithObjects:delete, nil]];
[menu setTargetRect:[self.myTable rectForRowAtIndexPath:indexPath] inView:self.myTable];
[menu setMenuVisible:YES animated:YES];
}
}
}
}
}
I have also implemented following methods
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == #selector(deleteFileListItem:))
{
return YES;
}
return NO;
}
-(BOOL)canBecomeFirstResponder
{
return YES;
}
and
- (void)deleteFileListItem:(id)sender
{
// Will perform action here
}
Please let me know if anything is missing or I am doing wrong.
I've been successful when attaching a long press gesture recognizer to each cell, not the entire table view. My guess is that that's the issue here.
I currently have a custom UITableViewCell which contains a UIImageView and trying to add a UITapGestureRecognizer on the UIImageView with no luck. here is snippet of the code.
//within cellForRowAtIndexPath (where customer table cell with imageview is created and reused)
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleImageTap:)];
tap.cancelsTouchesInView = YES;
tap.numberOfTapsRequired = 1;
tap.delegate = self;
[imageView addGestureRecognizer:tap];
[tap release];
// handle method
- (void) handleImageTap:(UIGestureRecognizer *)gestureRecognizer {
RKLogDebug(#"imaged tab");
}
I've also set userInteractionEnabled on the cell and the superview of the UIImageView but still no luck, any hints?
EDIT:
I've also remove cell's selection by cell.selectionStyle = UITableViewCellSelectionStyleNone; Could this be a problem
UIImageView's user interaction is disabled by default. You have to enable it explicitly to make it respond to touches.
imageView.userInteractionEnabled = YES;
Swift 3
This worked for me:
self.isUserInteractionEnabled = true
In my case it looks like :
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = CELL_ROUTE_IDENTIFIER;
RouteTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[RouteTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
}
if ([self.routes count] > 0) {
Route *route = [self.routes objectAtIndex:indexPath.row];
UITapGestureRecognizer *singleTapOwner = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(imageOwnerTapped:)];
singleTapOwner.numberOfTapsRequired = 1;
singleTapOwner.cancelsTouchesInView = YES;
[cell.ownerImageView setUserInteractionEnabled:YES];
[cell.ownerImageView addGestureRecognizer:singleTapOwner];
} else {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
And selector :
- (void)imageOwnerTapped:(UISwipeGestureRecognizer *)gesture {
CGPoint location = [gesture locationInView:self.tableView];
NSIndexPath *tapedIndexPath = [self.tableView indexPathForRowAtPoint:location];
UITableViewCell *tapedCell = [self.tableView cellForRowAtIndexPath:tapedIndexPath];
NSIndexPath *indexPath = [self.tableView indexPathForCell:tapedCell];
NSUInteger index = [indexPath row];
Route *route = [self.routes objectAtIndex:index];
}