web-dev-qa-db-ja.com

UICollectionViewCellからUICollectionViewのセルのindexPathにアクセスする方法

アクションが呼び出されたときにUICollectionViewCellをアニメーション化したい。
i UICollectionViewCellInterface BuilderUICollectionViewも。今、私のindexPathメソッドで正しいactionBtnAddToCardを取得したい。

それは私が今それを試す方法です(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:理解を深めるために投稿を編集しました。

20
brush51

ビューの階層がわかっていれば簡単です。

UIButton *button = (UiButton *) sender;

ボタンがこのような場合-> UITableViewCell-> button

その後、あなたはこのような細胞を得ることができます

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

ボタンがこのような場合-> UITableViewCell-> content view-> button

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

最後に、インデックスパスは次のように抽出できます。

NSIndexPath *indexPath = [self.table_View indexPathForCell:cell];
17
Shubhank
- (IBAction)actionAddToCart:(id)sender {
   NSIndexPath *indexPath;
   indexPath = [self.collectionView indexPathForItemAtPoint:[self.collectionView convertPoint:sender.center fromView:sender.superview]]; 
   ...
}
25
carmen_munich

ビューに依存しないでください。これを試して。

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

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

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

更新:Swift 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}
6
Echelon

Swift解決策:このような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)
5
Ishan Handa

このようにすることができます。indexPathsForVisibleItemsはビューに現在表示されているアイテムのNSIndexPathsの配列を返し、最初のオブジェクトは最初のオブジェクトを返します(ビューごとに1つのセルがある場合)。

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

Swift 3ソリューション: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)")
}
2
bpolat

特定のセルをアニメーション化する場合は、そのセルへの参照を取得する必要があります。単に呼び出す

[svc.collectionViewProdukte cellForItemAtIndexPath:indexPath];

何もしません。次のように、メソッドが返すセルを保持する必要があります。

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

その後、先に進み、アニメーション化します。

[UIView animateWithDuration:0.2f animations:^{
    cell.transform = CGAffineTransformMakeScale(0.5f, 0.5f);
}];
2
Tim
//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;
1
RFAustin

多くの答えがここにありますが、これはビュー階層に関係なく最短で便利です

- (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);
}
1
Asta ni enohpi

Xcode10。 Swift 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) 
0
Alex Kolovatov

ほとんど確実にUICollectionViewCellサブクラスがあります。プロパティを追加し、cellForItemAtIndexPathでindexPathを設定するだけです。

0
arsenius