MobileDev
MobileDev

Reputation: 3795

getting touch location of uicollectionviewcell

I am trying to get the touch location inside the selected UICollectionviewCell. I have a UIViewController, vc, containing a UICollectionView, collectionView, as its view. Inside the collectionView are UICollectionViewCells. The vc conforms to the UICollectionViewDelegate so preferably I would like to get the touched location inside the delegate callback, collectionView:(UICollectionView *)collection didSelectItemAtIndexPath:(NSIndexPath *)indexPath, (if possible). Any recommendation on how to do that? Thanks.

+--------------------------------------------+
| UICollectionView                           |
|                                            |
|  +-------------+       +-------------+     |
|  |  UICollec   |       |             |     |
|  |  tionView   |       |             |     |
|  |  Cell       |       |     *<---------------<Touch here
|  |             |       |             |     |
|  +-------------+       +-------------+     |
|                                            |
+--------------------------------------------+    

*UPDATE* I ended up detecting the tap on the UIViewCollectionView using the UIGestureRecognizer and then converting the tap point to the UICollectionViewCell view. Please let me know if there's a better way. Thanks.

-(void) viewDidLoad {
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
    [tapGesture setNumberOfTapsRequired:1];
    [self.collectionView addGestureRecognizer:tapGesture];
}

-(void) handleTap:(UIGestureRecognizer*) gesture {
    if (gesture.state == UIGestureRecognizerStateEnded) {
    CGPoint tappedPoint = [gesture locationInView:_collectionView];
    NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:tappedPoint];
    CollectionViewCell *cell = (CollectionViewCell*)[self.collectionView cellForItemAtIndexPath:indexPath];
    CGPoint pointWRTCell = [cell convertPoint:tappedPoint fromView:self.collectionView];
    NSLog(@"collectionView point(%1.1f,%1.1f); cell point (%1.1f,%1.1f)",
          tappedPoint.x,tappedPoint.y,pointWRTCell.x,pointWRTCell.y);
    }
}

Upvotes: 9

Views: 6653

Answers (4)

evolrof
evolrof

Reputation: 1

You should add the property for saving the touch location in the UICollectionViewCell.

@interface YourCollectionViewCell : UICollectionViewCell
@property (nonatomic, assign) CGPoint       touchPoint;
@end

Then add the event of touchesBegan in YourCollectionViewCell.m

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    self.touchPoint = [[touches anyObject] locationInView:self];
}

Finally, you may use the touchPoint in your UICollectionView

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    YourCollectionViewCell * cell = [collectionView cellForItemAtIndexPath:indexPath];
    NSLog(@"touch location %f, %f", cell.touchPoint.x, cell.touchPoint.y);
}

I think it's the easier way to get the touch location. And I'm using it in my codes.

Upvotes: 0

bhadresh
bhadresh

Reputation: 443

Get indexPath to try this code..

(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CellId" forIndexPath:[indexPath row]]; 

[[cell myButton] addTarget:self action:@selector(myClickEvent:event:) forControlEvents:UIControlEventTouchUpInside];

return cell;

}


(IBAction)myClickEvent:(id)sender event:(id)event {

NSSet *touches = [event allTouches];

UITouch *touch = [touches anyObject];

CGPoint currentTouchPosition = [touch locationInView:_myCollectionArray];

NSIndexPath *indexPath = [_myCollectionArray indexPathForItemAtPoint: currentTouchPosition];

}

Upvotes: 1

Jaybo
Jaybo

Reputation: 954

UIView has a method func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView?. To get the touch point, you can override this method in your collection view or collection view cell.

And there are methods like func convertPoint(_ point: CGPoint, toView view: UIView?) -> CGPoint for you to convert point in different coordinate systems.

Upvotes: 1

CrimsonChris
CrimsonChris

Reputation: 4641

You will likely need a custom cell to do this. didSelectItemAtIndexPath only tells you a cell was selected. Not where inside the cell it was touched.

Upvotes: 6

Related Questions