Как получить точки или пиксели на дюйм устройства, используя проект xamarin.iOS? - PullRequest
0 голосов
/ 10 сентября 2018

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

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

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

Другое решение, по-видимому, заключается в использовании замечательного Xamarin.Essentials . Тем не менее, они возвращают только High , Width и Scale . Но масштаб это не то, что я ищу ...

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

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

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


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

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

Нет общедоступного API для получения точек или пикселей на дюйм устройства в iOS.

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

iPad mini и iPad Air: они имеют одинаковую высоту (1024) и одинаковую шкалу (2x), но, поскольку ИЦП отличаются, получается, что они равны 7,9 и 9,7 соответственно ...

Затем была опция с кодом из XLabs , о которой я упоминал выше. Этот метод я нашел сначала в ветке на форумах Xamarin , а затем независимо в библиотеке XLabs . Это, тем не менее, было недостатком комментария о нарушении правил Apple ...

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

Привет, @ deczaloth,

Это не должно быть проблемой, так как Apple проверяет каждое приложение после отправки, чтобы увидеть, какие вызовы API сделаны, и получение аппаратной строки не является нарушением. Есть другие звонки, которые я видел отклоненными, но не hw.machine. Надеюсь, что это отвечает вашим интересам. Привет


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

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

отв

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

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);
0 голосов
/ 11 сентября 2018

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

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;
        }

     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...