This isn't so much a question as an explanation of how to solve this problem.
The first thing to realize is that the UICollectionView
does inherit from a UIScrollView
- so doing a standard lookup with a scroll view's content is the best solution.
Here's the problem I was addressing:
I had a UICollectionView
that had differing items in each cell - along with differing types of cells. I need the selection of a cell to cause an effect of the image in the cell to appear to expand and take over the whole screen. How I did the expansion is for another post.
The challenge was getting the cell's position on the screen so that the animating section would have a reference point from where to start.
So, to facilitate getting this information - consider the following code:
First note:
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...
Hopefully, this helps other folks that are trying to figure out how to say overlay something on the cell in an exact position, etc...
-(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);
}
It work for me.You can try yourself