#objective-c #macos #cocoa #core-graphics #nscollectionview
#objective-c #macos #cocoa #ядро-графика #nscollectionview
Вопрос:
В NSCollectionView отображается несколько элементов. У меня есть макет, подобный сетке.
Мне нужно определить элементы, которые видны в данный момент.
Согласно документации, существует метод
- (NSArray<NSCollectionViewItem *> *)visibleItems;
с описанием
Элементы, возвращаемые этим методом, представляют те, которые активны и в настоящее время управляются представлением коллекции. Этот массив может содержать элементы, которые находятся за пределами фактического видимого прямоугольника представления коллекции. Например, оно может содержать элементы, которые недавно были видны, но с тех пор были прокручены вне поля зрения. Чтобы проверить, действительно ли элемент виден, проверьте, пересекает ли его прямоугольник рамки
visibleRect
представления коллекции.
Итак, мне нужно вручную вычислить, какие элементы видны, на основе его frame
координат и visibleRect
CollectionView. Конечно, это нормально.
Однако меня беспокоит то, какие координаты visibleRect
возвращаются.
Обычно и это согласуется с документацией здесь, если у меня есть, скажем
NSImage *img = [[NSImage alloc] initWithContentsOfFile:...];
[imageView setFrame:NSMakeRect(0., -100., 300., 400.)];
[imageView setImage:img];
NSLog(..., [imageView visibleRect]);
NSLog(..., [imageView frame]);
тогда видимый прямоугольник будет иметь, как и ожидалось
x=0
y=100
width = 300
height = 300
И это полностью согласуется с документацией.
Однако в случае NSCollectionView
оно ведет себя по-другому. Если я создал элементы и отображается первый элемент, то visibleRect
будет отображаться
x = 0
y = 0
Теперь, если я немного прокрутю вниз, вывод будет
x = 0
y = some number > 0
Однако я ожидал бы, что оно должно возвращать другое y
значение. Потому что
Видимый прямоугольник представления отражает ту часть содержимого, которая фактически отображается, в терминах системы координат границ представления
Предполагается, что между элементами нет интервала и элементы идентичны
x = 0
y = (numItems - 1) * itemHeight
Такое поведение, конечно, не является проблемой. Я могу использовать эти значения для вычисления на основе возвращенных значений. Я хочу понять причину.
Чего я не понимаю?
P.S. По сути, NSCollectionView
visibleRect
вместе frame
со своими элементами ведет себя так, как если бы начало координат системы координат находилось в верхнем левом углу с y
увеличением вниз и x
увеличением вправо.
Комментарии:
1. Я не уверен, что вы пытаетесь сделать. Вы говорите: «Мне нужно определить элементы, которые в данный момент видны», но (как вы указываете) NSCollectionView уже делает это за вас. Кто такой «я» в этом случае? Ваш собственный подкласс NSCollectionView или NSCollectionViewLayout?
2. @mr.fixit Просмотр коллекции не выполняет этого автоматически. Оно может возвращать только массив элементов, которые использовались недавно. Однако, если пользователь прокручивает элемент, он все еще может использоваться, но на самом деле не виден. Чтобы определить действительно видимые элементы, вам нужно проверить, пересекает ли прямоугольник рамки элемента видимый прямоугольник представления коллекции. Когда вы начнете это делать, вам нужно разобраться с координатами. Поскольку в документации не написано, что NSCollectionView использует перевернутые координаты, я был сбит с толку.
Ответ №1:
NSCollectionView
использует перевернутую систему координат. Смотрите перевернутое свойство NSView
и перевернутые системы координат.