55

これは、この問題を解決する方法の説明ほどの質問ではありません。

最初に理解すべきことは、UICollectionViewが を継承していることです。そのUIScrollViewため、スクロール ビューのコンテンツで標準的なルックアップを行うことが最善の解決策です。

これが私が取り組んでいた問題です:

UICollectionView各セルに異なるアイテムがあり、異なるタイプのセルがありました。セル内の画像の効果が拡大して画面全体を占めるようにするには、セルを選択する必要があります。どのように拡張したかは、別の投稿で説明します。

課題は、画面上のセルの位置を取得して、アニメーション セクションがどこから開始するかの基準点を持つようにすることでした。

したがって、この情報を簡単に取得するには、次のコードを検討してください。

最初の注意:

UICollectionView *picturesCollectionView;
DrawingCell cell; // -> instanceof UICollectionViewCell with custom items.

// first, get the list of cells that are visible on the screen - you must do this every time
// since the items can change...  This is a CRITICAL fact.  You do not go through the
// entire list of cells - only those the collectionView indicates are visible.  Note 
// there are some things to watch out for - the visibles array does not match the indexPath.item
// number - they are independent.  The latter is the item number overall the cells, while
// the visibles array may have only 2 entries - so there is NOT a 1-to-1 mapping - keep
// that in mind.

NSArray *visibles = [self.picturesCollectionView visibleCells];

// now, cycle through the times and find the one that matches some criteria.  In my
// case, check that the cell for the indexPath passed matches the cell's imageView...
// The indexPath was passed in for the method call - note that the indexPath will point
// to the number in your datasource for the particular item - this is crucial.

for (int i=0; i<visibles.count; i++) {
    DrawingCell *cell = (DrawingCell *)visibles[i];
    if (cell.imageView.image == (UIImage *)images[indexPath.item]) {

        // at this point, we've found the correct cell - now do the translation to determine
        // what is it's location on the current screen...  You do this by getting the contentOffset
        // from the collectionView subtracted from the cell's origin - and adding in (in my case)
        // the frame offset for the position of the item I wish to animate (in my case the
        // imageView contained within my custom collection cell...

        CGFloat relativeX = cell.frame.origin.x - self.picturesCollectionView.contentOffset.x + cell.imageView.frame.origin.x;
        CGFloat relativeY = cell.frame.origin.y - self.picturesCollectionView.contentOffset.y + cell.imageView.frame.origin.y;

        // I now have the exact screen coordinates of the imageView - so since I need this
        // to perform animations, I save it off in a CGRect - in my case, I set the size
        // exactly to the size of the imageView - so say you were doing a Flicker display
        // where you wanted to grow a selected image, you get the coordinates of the image
        // in the cell and the size from the displayed image...

        UIImageView *image = cell.imageView;

        // selectedCell is a CGRect that's global for the sake of this code...

        selectedCell = cell.frame;
        selectedCell.origin.x = relativeX;
        selectedCell.origin.y = relativeY;
        selectedCell.size.width = cell.imageView.frame.size.width;
        selectedCell.size.height = cell.imageView.frame.size.height;
    }
}

// done.  I have my coordinates and the size of the imageView I wish to animate and grow...

うまくいけば、これは、セル上の正確な位置に何かをオーバーレイする方法などを理解しようとしている他の人々に役立ちます...

4

7 に答える 7

41

あなたの質問の最初の部分はかなり明確ですが、2番目の部分は?? とにかく、取得したいのがコレクション内の選択セルのフレームである場合は、これを使用できます:

UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
CGRect cellRect = attributes.frame;

詳細はこちら

于 2013-02-06T19:42:14.310 に答える
20

@Alivin を使用したソリューションlayoutAttributesForItemAtIndexPathは機能しますが、ユーザーに表示される提示/現在のスクロール ビューに対してのみ機能します。

つまり、最初に表示された表示セルを選択すると、実際の が表示されますが、frameスクロールするframe、 に偏差が生じ、必要な座標が取得されません。

これがconvertPoint:toViewを使用する必要がある理由です:

let realCenter = collectionView.convertPoint(cell.center, toView: collectionView.superview)

基本的に、このメソッドは 1 つのビューでポイント (cell.center) を取得し、そのポイントを別のビュー (collectionView.superview) 座標系に変換します。これはまさに必要なものです。

したがって、realCenterには、実際に選択されたセルの座標が常に含まれます。

于 2015-12-24T09:39:49.380 に答える
9

私も以前にこれを行いました。しばらく時間がかかりましたが、可能です。

あなたが使用する必要があります

[currentImageView.superview convertRect:currentImageView.frame toView:translateView]

ここで、currentImageViewは、ユーザーがタップした画像です。スーパービューがセルになります。画像の長方形を実際には別のビューにある場所に変換したいとします。ここでは、そのビューを「translateView」と呼びます。

では、translateViewとは何ですか?ほとんどの場合、それはただself.viewです。

これにより、画像がテーブルのどこにあるかに一致する画像ビューの新しいフレームが得られます。それができたら、画像を拡大して画面全体を占めることができます。

これは、画像をタップしてから画像を展開し、画像のパンを可能にする新しいコントローラーを表示するために使用するコードの要点です。

https://gist.github.com/farhanpatel/4964372

于 2013-02-15T23:19:50.767 に答える
1

別の方法は、イベントを使用して、質問に対するすべての回答ではないにしても、ほとんどの回答を提供することです。

タッチ イベントがこれらすべてを開始すると推測するので、意味のあるものを実装しましょう。

  //First, trap the event in the collectionView controller with;

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{

   // lets ensure it's actually visible (yes we got here from a touch event so it must be... just more info)
   if ([self.collectionView.indexPathsForVisibleItems containsObject:indexPath]) {

     // get a ref to the UICollectionViewCell at indexPath
     UICollectionViewCell *cell =(UICollectionViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];

     //finally get the rect for the cell
     CGRect cellRect = cell.frame


      // do your processing here... a ref to the cell will allow you to drill down to the image without the headache!!


  }
}

ああ...ハッピーアワーに急いで出かける前に、読み進めることを忘れないでください。

   <UICollectionViewDelegate> (hint - it's needed)  
于 2013-07-03T02:54:51.463 に答える