ios ibaction uicollectionview nsindexpath uicollectionviewcell

ios - cómo acceder desde UICollectionViewCell al indexPath de la celda en UICollectionView



ibaction nsindexpath (11)

Usar código como [[button superview] superview] es frágil y no a prueba de futuro; de hecho, ni siquiera está garantizado para trabajar en todas las versiones de iOS a menos que lo pruebes explícitamente. Siempre uso un método iterativo de ayuda para este propósito:

- (UIView *)superviewWithClassName:(NSString *)className fromView:(UIView *)view { while (view) { if ([NSStringFromClass([view class]) isEqualToString:className]) { return view; } view = view.superview; } return nil; }

Luego lo llamo desde el controlador de botones como tal: -

- (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... } }

ACTUALIZACIÓN: versión rápida de superviewWithClassName . Lo convirtió en un método de clase ya que nunca hace referencia a 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 }

y algún código para llamarlo, ya sea desde prepareForSegue o desde un manejador de botones: -

guard let cell = UIView.superviewWithClassName("UICollectionViewCell", fromView: sender as? UIView) as? UITableViewCell else {return}

quiero animar el UICollectionViewCell cuando se UICollectionViewCell acción.
He hecho UICollectionViewCell en Interface Builder , UICollectionView también. Ahora quiero obtener el indexPath correcto en mi método actionBtnAddToCard .

esa es la forma en que lo intento ahora (método en 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 es viewController que hereda UICollectionView.
cómo acceder al indexPath correcto?

ACTUALIZACIÓN 1: publicación editada para una mejor comprensión.


Si desea animar una celda específica, necesita obtener una referencia a esa celda. Simplemente llamando

[svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];

no hace nada. Debe mantener la celda que devuelve el método, como esta:

UICollectionViewCell *cell = [svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];

Después de eso, adelante y anima:

[UIView animateWithDuration:0.2f animations:^{ cell.transform = CGAffineTransformMakeScale(0.5f, 0.5f); }];


si conoce la jerarquía de vista, es fácil.

UIButton *button = (UiButton *) sender;

si el botón es así -> UITableViewCell -> botón

entonces puedes obtener una celda como esta

UITableViewCell *cell = (UITableViewCell *)[button superview];

si el botón es así -> UITableViewCell -> vista de contenido -> botón

UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];

y, finalmente, la ruta del índice se puede extraer de esta manera

NSIndexPath *indexPath = [self.table_View indexPathForCell:cell];


- (IBAction)actionAddToCart:(id)sender { NSIndexPath *indexPath; indexPath = [self.collectionView indexPathForItemAtPoint:[self.collectionView convertPoint:sender.center fromView:sender.superview]]; ... }


//Note: this is for a storyboard implementation // here is code for finding the row and section of a textfield being edited in a uicollectionview UIView *contentView = (UIView *)[textField superview]; UICollectionViewCell *cell = (UICollectionViewCell *)[contentView superview]; cell = (UICollectionViewCell *)[contentView superview]; // determine indexpath for a specific cell in a uicollectionview NSIndexPath *editPath = [myCollectionView indexPathForCell:cell]; int rowIndex = editPath.row; int secIndex = editPath.section;


No dependas de la vista. Prueba esto.

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.collectionView]; NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:buttonPosition]; NSLog(@"%ld", (long)indexPath.row);


Puede hacerlo así, indexPathsForVisibleItems devolverá una matriz de NSIndexPaths para los elementos actualmente visibles en la vista y el primer objeto devolverá la primera (si tiene una celda por vista).

NSIndexPath *indexPath = [[svc.collectionViewProdukte indexPathsForVisibleItems] firstObject]


Es casi seguro que tengas una subclase UICollectionViewCell. Simplemente agregue una propiedad y establezca indexPath en cellForItemAtIndexPath.


Aunque hay muchas respuestas que encontré aquí, esta será la más breve y útil, independientemente de la jerarquía de vistas

- (void) actionAddToCart:(id)sender { id view = [sender superview]; while (view && [view isKindOfClass:[UICollectionViewCell class]] == NO) { view = [view superview]; } NSIndexPath *thisIndexPath = [self.collectionView indexPathForCell:view]; NSLog(@"%d actionAddToCart pressed",thisIndexPath.row); }


Solución Swift : una extensión UICollectionView como esta puede ser útil para esto.

extension UICollectionView { func indexPathForView(view: AnyObject) -> NSIndexPath? { let originInCollectioView = self.convertPoint(CGPointZero, fromView: (view as! UIView)) return self.indexPathForItemAtPoint(originInCollectioView) } }

El uso se vuelve fácil en todas partes.

let indexPath = collectionView.indexPathForView(button)


Solución Swift 3: basada en la respuesta de Ishan Handa

extension UICollectionView { func indexPathForView(view: AnyObject) -> IndexPath? { let originInCollectioView = self.convert(CGPoint.zero, from: (view as! UIView)) return self.indexPathForItem(at: originInCollectioView) as IndexPath? } }

Uso:

func deleteCell(sender:UIButton){ var indexPath:IndexPath? = nil indexPath = self.collectionView.indexPathForView(view: sender) print("index path : /(indexPath)") }