如何从UICollectionViewCell访问UICollectionView细胞的indexP

2019-07-05 06:28发布

我想动画的UICollectionViewCell当动作被调用。
我已经做了UICollectionViewCellInterface BuilderUICollectionView也。 现在我想以获得正确的indexPathactionBtnAddToCard方法。

这就是我尝试它现在(在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是继承了UICollectionView的的viewController。
如何存取权限正确indexPath?

更新1:修改后的更好的理解。

Answer 1:

如果你知道视图层次很容易。

UIButton *button = (UiButton *) sender;

如果按钮是这样的- >的UITableViewCell - >按钮

那么你可以得到的细胞像这样

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

如果按钮是这样的- >的UITableViewCell - >内容视图- >按钮

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

最后索引路径可以提取这样

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


Answer 2:

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


Answer 3:

不依赖于视图。 试试这个。

CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.collectionView];
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:buttonPosition];

NSLog(@"%ld", (long)indexPath.row);


Answer 4:

使用类似代码[[button superview] superview]是易碎和不面向未来; 事实上,它甚至没有保证在所有iOS版本的工作,除非你明确地对它进行测试。 我总是用迭代助手方法用于此目的: -

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

然后,我把它从像这样的按钮处理程序: -

- (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:雨燕版superviewWithClassName 。 它制造一个类的方法,因为它从来没有引用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或按钮的处理程序: -

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


Answer 5:

迅速方案:一种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)


Answer 6:

你可以像这样做,indexPathsForVisibleItems将返回在视图和第一对象当前可见返回第一个(如果你有每个视图一个小区)项目NSIndexPaths的阵列。

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


Answer 7:

如果你想动画一个特定的细胞,你需要获得该单元格的引用。 简单地调用

[svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];

什么也没做。 你需要保持该方法返回,这样的细胞:

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

在此之后,继续和动画:

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


Answer 8:

斯威夫特3解决方案:基于依禅函大的回答:

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)")
}


Answer 9:

//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;


Answer 10:

尽管许多答案,我发现在这里。这将是最短的和有用的,不论视图层次结构

- (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);
}


Answer 11:

你几乎可以肯定有一个UICollectionViewCell子类。 只需添加一个属性,并设置在cellForItemAtIndexPath的indexPath。



Answer 12:

Xcode10。 雨燕4.2的版本。

extension UICollectionView {

  func indexPathForView(view: AnyObject) -> IndexPath? {
      guard let view = view as? UIView else { return nil }
      let senderIndexPath = self.convert(CGPoint.zero, from: view)
      return self.indexPathForItem(at: senderIndexPath)
  }

}

用法:

// yourView can be button for example
let indexPath = collectionView.indexPathForView(view: yourView) 


文章来源: how to access from UICollectionViewCell the indexPath of the Cell in UICollectionView