Это не просто. Я не уверен, что есть хороший способ. Я могу предложить подход, но я не подтвердил, что он работает надежно:
Во-первых, вы можете использовать CGDisplayScreenSize()
, чтобы получить физический размер экрана в миллиметрах. Вы можете получить CGDirectDisplayID
для экрана от NSScreen
, который вы, в свою очередь, можете получить из окна. Получите deviceDescription
на экране и получите значение для клавиши "NSScreenNumber"
. Это может потребоваться преобразовать в CGDirectDisplayID
.
Проблема в том, что режим отображения может не заполнять экран. Это может быть почтовый ящик или столб. Или это может быть растянуто. Это должно быть довольно необычно в наши дни, но все же возможно. Вы можете получить режим отображения, используя CGDisplayCopyDisplayMode()
. Чтобы определить, растянуты ли вы, вы можете проверить его ioFlags
, чтобы увидеть, содержат ли они битовую маску kDisplayModeStretchedFlag
(объявленную в IOKit).
Если она растянута, frame
экрана нужно будет сопоставить с его размер в миллиметрах отдельно для осей X и Y. Предполагается, что frame.width
(в точках) экрана соответствует полной физической ширине и аналогично высоте.
Если режим не растянут, вам придется проверить соотношение сторон кадра и физический размер экрана, чтобы увидеть, является ли он буквой или рамкой. Если аспект крысы ios очень близок, то, вероятно, нет. Этот случай аналогичен растянутому случаю, но сопоставления ширины и высоты должны быть эквивалентны.
Если аспектные крысы ios значительно отличаются, то вы сравниваете их. Если физическое соотношение сторон экрана больше, чем у кадра, то экран физически шире, чем используемый режим (в виде столбика). Итак, вы вычисляете отображение из точек в миллиметры с двух высот. Если физическое соотношение сторон меньше, чем логическое, то режим имеет формат «почтовый ящик» и вы используете ширину для вычисления отображения.