The NSCollectionView displays multiple items. I have a Grid like layout.
I need to determine the items that are currently visible.
According to the documentation there is a method
- (NSArray<NSCollectionViewItem *> *)visibleItems;
with the description
The items returned by this method represent the ones that are active and currently being managed by the collection view. This array may contain items that are outside of the collection view’s actual visible rectangle. For example, it may contain items that were recently visible but have since been scrolled out of view. To test whether an item is actually visible, check to see if its frame rectangle intersects the
visibleRect
of the collection view.
So I need to manually calculate which items are visible based on its frame
coordinates and visibleRect
of the collectionView. It's fine of course.
However, what bothers me is which coordinates visibleRect
returns.
Usually and it agrees with the documentation here if I have lets say
NSImage *img = [[NSImage alloc] initWithContentsOfFile:...];
[imageView setFrame:NSMakeRect(0., -100., 300., 400.)];
[imageView setImage:img];
NSLog(..., [imageView visibleRect]);
NSLog(..., [imageView frame]);
then the visible rectangle will have as expected
x=0
y=100
width = 300
height = 300
And this fully agrees with the documentation.
However, in the case of the NSCollectionView
it behaves differently.
If I created items and the first item is displayed, then visibleRect
will display
x = 0
y = 0
Now if I scroll a little bit down the output will be
x = 0
y = some number > 0
However, I would expect that it should return a different y
value. Because
A view's visible rectangle reflects the portion of the contents that are actually displayed, in terms of the view's bounds coordinate system
Assuming that there is no spacing between items and items are identical
x = 0
y = (numItems - 1) * itemHeight
This behavior is not a problem of course. I can use these values to calculate things based on the returned values. I want to understand the reason.
What am I missing?
P.S. Essentially NSCollectionView
visibleRect
together with frame
of its items behaves as if the origin of the coordinate system were in the top left corner with y
increasing down and x
increasing right.
NSCollectionView
uses a flipped coordinate system.
See the flipped property of NSView
and Flipped Coordinate Systems.