Как получить очки или пиксели на дюйм устройства с помощью проекта xamarin.iOS?

Вопрос просто такой, как указано в заголовке:

Как узнать плотность пикселей или точек (на дюйм) устройства экрана в проекте Xamarin.iOS?

Я нашел несколько «решений», таких как тот, что заявил @JohnHardman в сообщении на форумах Xamarin (в котором используется код из XLabs, также предложенный в ответ @SKall в другом потоке SO, и, как указано на форуме, я не мог использовать, поскольку он «вероятно» вызовет отказ в Apple Store).

Другое решение, похоже, заключается в использовании замечательного Xamarin.Essentials. Тем не менее, они возвращают только Высокий, Ширина и Шкала. Но масштаб - это не то, что я ищу ...

Итак, знает ли кто-нибудь путь по этому, казалось бы, легкому / тривиальному пути? (почему это должно быть так сложно, такая простая задача?)

Что ты хочешь делать ? Хотите ли вы определить модель устройства по ширине и высоте экрана?

Lucas Zhang 10.09.2018 11:58

Привет, @LucasZ, на самом деле я хочу получить размер диагонали экрана устройства в дюймах, чтобы определить, меньше или больше устройство, чем «критическая» мера, которую я определяю ...

Deczaloth 10.09.2018 12:03
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
667
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете получить диагональ экрана, сопоставив модель телефона с размером экрана устройства. Попробуйте использовать следующий код.

CGSize screenSize = UIScreen.MainScreen.Bounds.Size;
float screenInch;

 // if device is iPhone
 if (UIDevice.CurrentDevice.UserInterfaceIdiom==UIUserInterfaceIdiom.Phone)
    {
      if (screenSize.Height==812)//iPnone X
        {
          screenInch = 5.8f;
        }

      else if (screenSize.Height == 736) //iPhone 6p 7p 8p
        {
          screenInch = 5.5f;
        }

      else if (screenSize.Height == 667)//iPhone 6 7 8
        {
          screenInch = 4.7f;
        }

      else if (screenSize.Height == 568) // iPhone 5 5s 5c se
        {
           screenInch = 4.0f;
        }

       else //iPhone 4s and before
        {
           screenInch = 3.5f;
        }

     }

Спасибо за ответ @LucasZ. Это определенно вариант, но ... мне не разрешили использовать его из-за случая с iPad mini и iPad Air: они имеют одинаковую высоту (1024) и одинаковый масштаб (2x), но поскольку PPI разные, оказывается, что они 7,9 дюйма и 9,7 дюйма соответственно ...

Deczaloth 11.09.2018 10:23
Ответ принят как подходящий

Чтобы прочитать метод, который я использовал для окончательного получения плотности пикселей, пожалуйста, прочтите ниже раздел «Мой последний метод». Если вы хотите узнать, как я к этому пришел, продолжайте читать.


Итак, я провел дополнительное исследование и пришел к решению, которое меня устраивает. Я поделюсь этим для потомков.

Прежде всего, мне сказал @ColeX (член команды Xamarin), который

There is no public API for getting points or pixels per inch of device in iOS.

Так что нужен другой подход. Сначала я подумал, что могу получить размер экрана с помощью Switch-Casing размер в пикселях, который доступен в общедоступном API, но, как я писал в комментарии выше к @LucasZ, это было бы неточно, поскольку

iPad mini and iPad Air: they both have the same height (1024) and the same scale (2x), but since the PPI are different it turns out that they are 7.9 in and 9.7 in respectively...

Затем был вариант с кодом из XLabs, о котором я упоминал выше. Этот метод я нашел сначала в нить в Форумы Xamarin, а затем независимо в библиотека XLabs. Тем не менее, у этого был недостаток комментария о нарушении руководящих принципов Apple ...

К счастью, после дальнейших исследований и дополнительных вопросов и ответов, в Форумы Xamarin в другой поток @LandLu (также член команды Xamarin) указал мне на другая библиотека: эта библиотека также делает таинственный запрос к hw.machine. Поэтому я решил спросить автора о риске использования такого метода и он ответил:

Hi @deczaloth,

It shouldn't be a problem as Apple checks every app upon submission to see what API calls are made and retrieving the hardware string hasn't been a violation. There are other calls I have seen rejected but not hw.machine. Hope that answers your concern. Regards


Мой последний метод был:

  1. Получите подробную модель iOS, получив строку оборудования с помощью специальная библиотека / nuGet / code (или обратитесь к коду в ПРИЛОЖЕНИЕ).
  2. Switch-Case - подробная модель, полученная на предыдущем шаге, с общедоступной информацией о размерах экрана в дюймах (эта информация является общедоступной и существует множество источников, например печально известный iosres.com).
  3. Используйте общедоступный API (UIScreen.MainScreen.Bounds.Size), чтобы получить размер диагонали экрана в пикселях (базовая математика Пифагора) и с его помощью вычислить плотность пикселей: pixels per inch = diagonal-size-in-pixels/diagonal-size-in-inches.
  4. Вуаля!

ПРИЛОЖЕНИЕ

Код для получения строки оборудования:

using System;
using System.Runtime.InteropServices;
using ObjCRuntime;

public static string GetiOSModel() =>
    GetSystemProperty(string property);

public static string GetSystemProperty(string property)
{
    var pLen = Marshal.AllocHGlobal(sizeof(int));
    sysctlbyname(property, IntPtr.Zero, pLen, IntPtr.Zero, 0);
    var length = Marshal.ReadInt32(pLen);
    var pStr = Marshal.AllocHGlobal(length);
    sysctlbyname(property, pStr, pLen, IntPtr.Zero, 0);
    return Marshal.PtrToStringAnsi(pStr);
}

/// <summary>
/// Sysctlbynames the specified property.
/// </summary>
/// <param name = "property">The property.</param>
/// <param name = "output">The output.</param>
/// <param name = "oldLen">The old length.</param>
/// <param name = "newp">The newp.</param>
/// <param name = "newlen">The newlen.</param>
/// <returns>System.Int32.</returns>
[DllImport(Constants.SystemLibrary)]
internal static extern int sysctlbyname(
[MarshalAs(UnmanagedType.LPStr)] string property,
IntPtr output,
IntPtr oldLen,
IntPtr newp,
uint newlen);

Другие вопросы по теме