如何从UICollectionViewCell访问UICollectionView中Cell的indexPath
我想animationUICollectionViewCell
行动时被调用。
我在Interface Builder
UICollectionView
也做了UICollectionView
。 现在我想在我的actionBtnAddToCard
方法得到正确的indexPath
。
这就是我现在尝试的方式(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是inheritanceUICollectionView的viewController。
如何访问正确的indexPath?
更新1:编辑后更好的理解。
如果您知道视图层次结构,那很容易。
UIButton *button = (UiButton *) sender;
如果button是这样的– > UITableViewCell – >button
那么你可以得到这样的细胞
UITableViewCell *cell = (UITableViewCell *)[button superview];
如果button是这样的– > UITableViewCell – >内容视图 – >button
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
最后可以像这样提取索引path
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]]; ... }
使用像[[button superview] superview]
这样的代码是脆弱的,而不是面向未来的; 实际上,除非明确地testing,否则甚至不能保证可以在所有的iOS版本上运行。 我总是使用迭代辅助方法来达到这个目的:
- (UIView *)superviewWithClassName:(NSString *)className fromView:(UIView *)view { while (view) { if ([NSStringFromClass([view class]) isEqualToString:className]) { return view; } view = view.superview; } return nil; }
然后我从button处理程序中调用它:
- (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... } }
更新: superviewWithClassName
Swift版本。 使它成为一个类方法,因为它从不引用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 }
和一些代码来调用它,无论是从prepareForSegue
或button处理程序: –
guard let cell = UIView.superviewWithClassName("UICollectionViewCell", fromView: sender as? UIView) as? UITableViewCell else {return}
不要依赖于视图。 尝试这个。
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.collectionView]; NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:buttonPosition]; NSLog(@"%ld", (long)indexPath.row);
如果要为特定的单元格设置animation,则需要获取对该单元格的引用。 只需打电话
[svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];
什么也没做。 您需要保持方法返回的单元格,如下所示:
UICollectionViewCell *cell = [svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];
之后,继续animation:
[UIView animateWithDuration:0.2f animations:^{ cell.transform = CGAffineTransformMakeScale(0.5f, 0.5f); }];
你可以这样做,indexPathsForVisibleItems将返回当前在视图中可见的项目的NSIndexPaths数组,并且第一个对象返回第一个(如果每个视图有一个单元格)。
NSIndexPath *indexPath = [[svc.collectionViewProdukte indexPathsForVisibleItems] firstObject]
Swift解决scheme:像这样的UICollectionView扩展可能对此有用。
extension UICollectionView { func indexPathForView(view: AnyObject) -> NSIndexPath? { let originInCollectioView = self.convertPoint(CGPointZero, fromView: (view as! UIView)) return self.indexPathForItemAtPoint(originInCollectioView) } }
用处变得容易到处。
let indexPath = collectionView.indexPathForView(button)
Swift 3解决scheme:基于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? } }
用法:
func deleteCell(sender:UIButton){ var indexPath:IndexPath? = nil indexPath = self.collectionView.indexPathForView(view: sender) print("index path : \(indexPath)") }
//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;
即使我在这里find许多答案,这将是最短和有用的,不pipe视图的层次结构
- (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); }
你几乎可以肯定有一个UICollectionViewCell子类。 只需添加一个属性,并在cellForItemAtIndexPath中设置indexPath。