Reputation: 3795
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
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
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
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
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