Как работает метод convertRectToScreen: класса NSWindow

В окне три представления (NSView). Синее вложено в зеленое, а зеленое в красное. Красное представление находится прямо в окне. 


Посмотрим какие результаты выдаст код:

NSRect theRedRect = [self.window convertRectToScreen:[self.redView frame]];
NSRect theGreenRect = [self.window convertRectToScreen:[self.greenView frame]];
NSRect theBlueRect = [self.window convertRectToScreen:[self.blueView frame]];

Если расположить окно у нижнего левого края экрана:

Все X- и Y-координаты равны нулю. По умолчанию отсчет координат начинается с нижнего левого угла.

Если сдвинуть окно на 100 x 100 вверх и влево, то X- и Y-координаты изменятся соответственно:


Если сдвинуть красное представление на 20 px вправо:

Координаты вложенных представлений не изменились. X-координата красного представления тоже сдвинулась на 20 px. 

Посмотрим, что будет, если сдвинуть зеленые и синие представления на 20 px каждое:


В общем вывод тут такой, что координаты фрейма в окне (или родительском представлении) переводятся в координаты экрана.

Но тут есть один нюанс. На рисунке выше у всех трех представлений показаны одинаковые координаты, хотя на экране они занимают разные позиции. Почему так? Если вы посмотреть на код приводившийся в начале поста, то увидите, что при вызове геттера frame у представления мы получаем координаты данного представления относительно родительского контейнера. Поэтому при переводе координат зеленого и синего представления результат будет таким же как и красного представления, потому что все они сдвинуты на 20 px в своих родительских контейнерах: красное - в окне, зеленое - в красном, синее - в зеленом. 

Следовательно для того чтобы получить координаты на экране для вложенных представлений посредством вызова метода convertRectToScreen: у NSWindow надо сначала преобразовать их координаты в оконные, а потом из оконных можно уже получить экранные.

исходники