how to access from UICollectionViewCell the indexPath of the Cell in UICollectionView
Solution 1
if you know the view hierarchy it is easy.
UIButton *button = (UiButton *) sender;
if the button is like this - > UITableViewCell - > button
then you can get cell like this
UITableViewCell *cell = (UITableViewCell *)[button superview];
if the button is like this - > UITableViewCell - > content view -> button
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
and finally index path can be extracted like this
NSIndexPath *indexPath = [self.table_View indexPathForCell:cell];
Solution 2
- (IBAction)actionAddToCart:(id)sender {
NSIndexPath *indexPath;
indexPath = [self.collectionView indexPathForItemAtPoint:[self.collectionView convertPoint:sender.center fromView:sender.superview]];
...
}
Solution 3
Do Not Depend on view. Try this.
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:buttonPosition];
NSLog(@"%ld", (long)indexPath.row);
Solution 4
Using code like [[button superview] superview]
is fragile and not future-proof; indeed, it's not even guaranteed to work on all iOS versions unless you explicitly test it. I always use an iterative helper method for this purpose:-
- (UIView *)superviewWithClassName:(NSString *)className fromView:(UIView *)view
{
while (view)
{
if ([NSStringFromClass([view class]) isEqualToString:className])
{
return view;
}
view = view.superview;
}
return nil;
}
Then I call it from the button handler like so:-
- (IBAction)buttonClicked:(id)sender
{
UIButton *button = (UIButton *)sender;
UICollectionViewCell *cell = (UICollectionViewCell *)
[self superviewWithClassName:@"UICollectionViewCell"
fromView:button];
if (cell)
{
NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
// do whatever action you need with the indexPath...
}
}
UPDATE: Swift version of superviewWithClassName
. Made it a class method since it never references self
.
static func superviewWithClassName(className:String, fromView view:UIView?) -> UIView? {
guard let classType = NSClassFromString(className) else {
return nil
}
var v:UIView? = view
while (v != nil) {
if v!.isKindOfClass(classType) {
return v
}
v = v!.superview
}
return nil
}
and some code to call it, either from prepareForSegue
or a button handler:-
guard let cell = UIView.superviewWithClassName("UICollectionViewCell", fromView: sender as? UIView) as? UITableViewCell else {return}
Solution 5
Swift solution: A UICollectionView extension like this one can be useful for this.
extension UICollectionView {
func indexPathForView(view: AnyObject) -> NSIndexPath? {
let originInCollectioView = self.convertPoint(CGPointZero, fromView: (view as! UIView))
return self.indexPathForItemAtPoint(originInCollectioView)
}
}
Usage becomes easy everywhere.
let indexPath = collectionView.indexPathForView(button)
Comments
-
brush51 about 3 years
i want to animate the
UICollectionViewCell
when action is called.
i have doneUICollectionViewCell
inInterface Builder
, theUICollectionView
also. Now i want to get the correctindexPath
at myactionBtnAddToCard
method.thats the way i try it now (method in ProduktViewCell.m):
- (IBAction)actionAddToCart:(id)sender { XLog(@""); // see this line NSIndexPath *indexPath = ??** how can i access the correct indexPath**??; SortimentViewController *svc = [[SortimentViewController alloc] initWithNibName:@"SortimentViewController_iPad" bundle:[NSBundle mainBundle]]; [svc.collectionViewProdukte cellForItemAtIndexPath:indexPath]; [svc collectionView:svc.collectionViewProdukte didSelectItemAtIndexPath:indexPath]; }
SortimentViewController is the viewController which inherits the UICollectionView.
how to acces the correct indexPath?UPDATE 1: edited post for better understanding.
-
brush51 over 11 yearsbut how can i get the indexPath? i will update my question for better understanding
-
Tim over 11 yearsAn indexPath is just a way to refer to a specific cell. Without knowing what your app does, I have no way to guess which cell you are trying to animate.
-
Tim over 11 yearsTo get the first cell, it would be something like this: NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
-
brush51 over 11 yearsthats my problem. How can i find out on which cells action is called?
-
Tim over 11 yearsThat really depends on the structure of your app. If each cell has an 'add to cart' button, you might think about putting that button inside the cell (which should be a UICollectionViewCell subclass), and make sure the button is calling a method on the cell itself (not the view controller). Then use a delegation pattern to call some logical method on the view controller: something like -(void)addToCartButtonPressedForCell:(UICollectionViewCell *)cell];
-
ChuckKelly over 10 yearsyeah , bit confused what u mean when talking in the context of a collection view, would you mind shoing us a full action snippet?
-
iSeeker about 10 yearsThe OP had asked for a solution in the case for UICollectionView not UITableViewCell.. IMHO this answer sends the wrong message to readers.. Please edit to point how to do this in UICollectionView.
-
MickyD over 9 yearsConsider adding an explanation
-
Echelon about 9 years
[[button superview] superview]
is fragile. I added a safer answer below. -
lee over 8 yearsUITableViewCell *cell = (UITableViewCell *)[[button superview] superview]; help me.when I have: button->collectionview->UItableviewcell
-
Bryan Bryce over 8 yearsThis works until you enable reordering of items, then you have to manually go in and fix indexPath property for all the affected cells.
-
Brian Sachetta over 8 yearsSorry but calling superview a bunch of times is very hacky. Changes to the view hierarchy could easily break such calls. And this original question does not deal with UITableView.
-
Brian Sachetta over 8 yearsUICollectionView supports the indexPathForCell: method as well. If you update this answer to reference UICollectionView / UICollectionViewCell rather than UITableView / UITableViewCell I will upvote.
-
tuandapen about 7 yearsGood solution. Thanks
-
iRon3.0 over 4 yearssuperview of a superview is a dangerous hack. i know because i use it 😂