UITableView has the method rectForRowAtIndexPath:, but this does not exist in UICollectionView. I'm looking for a nice clean way to grab a cell's bounding rectangle, perhaps one that I could add as a category on UICollectionView.
Asked
Active
Viewed 4.0k times
73
5 Answers
150
The best way I've found to do this is the following:
Objective-C
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
Swift
let attributes = collectionView.layoutAttributesForItem(at: indexPath)
Then you can access the location through either attributes.frame or attributes.center
simon
- 2,585
- 4
- 18
- 21
-
16This will give the absolute position of the cell related to the superview `CGRect cellFrameInSuperview = [self.collectionView convertRect:attributes.frame toView:[self.collectionView superview]];` – Maverick Nov 16 '15 at 05:56
53
Only two lines of code is required to get perfect frame :
Objective-C
UICollectionViewLayoutAttributes * theAttributes = [collectionView layoutAttributesForItemAtIndexPath:indexPath];
CGRect cellFrameInSuperview = [collectionView convertRect:theAttributes.frame toView:[collectionView superview]];
Swift 4.2
let theAttributes = collectionView.layoutAttributesForItem(at: indexPath)
let cellFrameInSuperview = collectionView.convert(theAttributes.frame, to: collectionView.superview)
Iulian Onofrei
- 8,409
- 9
- 67
- 106
Shaik Riyaz
- 10,661
- 7
- 50
- 69
-
1This is what I was looking for, it gives you the updated frame while scrolling. – Marc Jan 07 '16 at 23:45
18
in swift 3
let theAttributes:UICollectionViewLayoutAttributes! = collectionView.layoutAttributesForItem(at: indexPath)
let cellFrameInSuperview:CGRect! = collectionView.convert(theAttributes.frame, to: collectionView.superview)
Spydy
- 2,467
- 18
- 18
9
in swift you can just do:
//for any cell in collectionView
let rect = self.collectionViewLayout.layoutAttributesForItemAtIndexPath(clIndexPath).frame
//if you only need for visible cells
let rect = cellForItemAtIndexPath(indexPath)?.frame
Victor --------
- 492
- 1
- 9
- 28
-2
How about
-(CGRect)rectForCellatIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [self cellForItemAtIndexPath:indexPath];
if (!cell) {
return CGRectZero;
}
return cell.frame;
}
as a category on UICollectionView?
#import <UIKit/UIKit.h>
@interface UICollectionView (CellFrame)
-(CGRect)rectForCellatIndexPath:(NSIndexPath *)indexPath;
@end
#import "UICollectionView+CellFrame.h"
@implementation UICollectionView (CellFrame)
-(CGRect)rectForCellatIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [self cellForItemAtIndexPath:indexPath];
if (!cell) {
return CGRectZero;
}
return cell.frame;
}
@end
TimD
- 7,684
- 2
- 23
- 33
-
This works, but gives the cell's frame as it is within its own view hierarchy (meaning every cell will have an origin of {0,0}). I need to know what the rect is within the table view. – akaru Sep 22 '12 at 20:46
-
Use `UIView`'s `convertRect:toView:` method to convert the rect relative to the collection view. – TimD Sep 24 '12 at 12:36
-
2cellForItemAtIndexPath path only returns a value for visible cells. If the cell at the indexPath is off screen it returns nil. – Ashley Mills Oct 10 '13 at 14:10
-
Works fine for visible cells, and OP did not specify visible cells or not. – phatmann Apr 15 '14 at 20:19
-
1
-
Your solution is fine; however, I'd amend it with the convertRect:toView: method as suggested. That's for two reasons: 1) that's the only reason for getting a cell's rect in this way; 2) this is essential part of peek-and-pop functionality. That it only works for visible cells is a lame criticism from per reason #2; you will never need the rect of an offscreen cell, which is why the means to do it is not provided by any other framework. I upvoted your answer, and I intend to employ it in my current project today. – James Bush Dec 14 '16 at 23:53
-
@JamesBush, I disagree with your comment. Firstly, I would not amend it with the `convertRect:toView:` method as it's too specific and not everyone needs it. Or maybe someone needs to convert it to the `superview of the `superview` of the collection view, but you're essentially saying to assume one's view hierarchy. Secondly, you also assume people's use cases. I, for example, actually do need the rect of an off-screen cell. – Iulian Onofrei May 07 '19 at 12:45
-
this is rect for cell with parent, not collectionView, u will see x,y = 0 – famfamfam Apr 03 '21 at 08:09