从UICollectionView获取单元格的屏幕位置

这不是解释如何解决这个问题的问题。

首先要认识到的是UICollectionView是从UIScrollViewinheritance而来的 – 所以使用滚动视图的内容进行标准查找是最好的解决scheme。

这是我正在处理的问题:

我有一个UICollectionView在每个单元中有不同的项目 – 以及不同types的单元格。 我需要select一个单元格,以使单元格中的图像的效果显现为展开并占据整个屏幕。 我如何扩展是另一个职位。

面临的挑战是让单元格在屏幕上的位置,以便animation部分从哪里开始有一个参考点。

所以,为了方便获取这些信息 – 请考虑以下代码:

首先注意:

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

希望这有助于其他人试图弄清楚如何在细胞上覆盖一些确切位置的东西等。

 -(void)collectionView:(UICollectionView *)cv didSelectItemAtIndexPath:(NSIndexPath *)indexPath; { UICollectionViewLayoutAttributes *attributes = [cv layoutAttributesForItemAtIndexPath:indexPath]; CGRect cellRect = attributes.frame; CGRect cellFrameInSuperview = [cv convertRect:cellRect toView:[cv superview]]; NSLog(@"%f",cellFrameInSuperview.origin.x); } 

它为我工作,你可以尝试自己

那么你的问题的第一部分是非常清楚的,第二个? 无论如何,如果你想得到的是你的集合中的select单元格的框架,你可以使用这个:

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

更多信息在这里

@Alivin解决scheme使用layoutAttributesForItemAtIndexPath工作,但只适用于用户看到的呈现/当前滚动视图。

意思是,如果你select第一个可见的单元格,你会得到实际的frame但是如果你滚动, frame将有一个偏差,你不会得到你需要的坐标。

这就是为什么你需要使用convertPoint:toView

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

基本上这个方法在一个视图中获取一个点(cell.center),并将该点转换为另一个视图(collectionView.superview)坐标系,这正是我们所需要的。

因此, realCenter将始终包含实际选定单元格的坐标。

我之前也做过这个。 它花了一段时间,但它是可能的。

你需要使用

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

currentImageView是用户点击的图像。 这是超级观点将是细胞。 您想要将图像的矩形转换为实际位于不同视图的位置。 这个视图在这里被称为“translateView”。

那么translateView是什么? 在大多数情况下,它只是self.view

这将为您的imageview提供一个新的框架,以满足您图像在桌面上的位置。 一旦你有,你可以扩大图像占据整个屏幕。

下面是我用来拍摄图像的代码,然后展开图像并显示允许平移图像的新控制器。

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

另一种方法是使用这些事件来提供大部分(如果不是全部的话)你的问题的答案。

我认为触摸事件将启动所有这一切,所以让我们实现一些有意义的事情;

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