Obtain the screen location of a cell from a UICollection view

综合技术 2017-11-15

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="" translation="" to="" determine="" what="" is="" it's="" location="" on="" current="" screen...="" you="" by="" getting="" contentoffset="" from="" collectionview="" subtracted="" cell's="" origin="" and="" adding="" in="" (in="" my="" case)="" frame="" offset="" for="" position="" of="" item="" i="" wish="" animate="" case="" imageview="" contained="" within="" custom="" collection="" cell...="" cgfloat="" relativex="cell.frame.origin.x" self.picturescollectionview.contentoffset.x="" +="" cell.imageview.frame.origin.x;="" relativey="cell.frame.origin.y" self.picturescollectionview.contentoffset.y="" cell.imageview.frame.origin.y;="" have="" exact="" screen="" coordinates="" so="" since="" need="" perform="" animations,="" save="" it="" off="" a="" cgrect="" case,="" set="" size="" exactly="" say="" were="" doing="" flicker="" display="" where="" wanted="" grow="" selected image,="" get="" image="" displayed="" image...="" uiimageview="" *image="cell.imageView;" selectedcell="" that's="" global="" sake="" code...="" 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.="" 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]];


It work for me.You can try yourself


Error on self.view.viewWithT... I'm trying to remove a view I previously added to the view on a UIViewController. The code is working on iOS 9, but crashes on 8.3 in the simulator. ...
微信伪造位置 叶孤城原创 小白:叶孤城,你上节讲如何突破微信的升级限制,让司空摘星嘲笑了,他说你只是乱扯。喂,你能用图来说明吗? 叶孤城:什么!我上节的图还不能说明吗!那只好上视频了。 微信多开 小白:喂,这个视频很卡喔,你不会提高帧率? 叶孤城:咦,帧率你也晓得?跟花满...
保护你的crash 尽管 APM 有相当多的采集指标,但假如只能监控一种数据,那么必然会选择 crash 。毫不客气的说, crash 在 APM 中绝对可以占据 80% 甚至更多的地位。因此,如果一旦 crash 采集的数据发生了异常,对于 APM 相关的开发人员来说,绝对是一个噩耗。 crash采...
iOS 多线程: 初步认识 几乎每个编程语言或者平台都会遇到多线程的问题, 说明多线程是一个非常重要且开发者必须了解和掌握的. 多线程也是面试官比较喜欢问的问题, 例如: 进程和线程的区别, Android 是否支持多进程? 线程池如何实现的? 锁机制? 多线程之间如何通信? 谈及 ...
Fake AppDelegate for Unit Testing in Swift One of the most important things of unit testing is that it shouldn’t have side effects. If you don’t pay attention, you may have unexpected behav...