Вопрос просто такой, как указано в заголовке:
Как узнать плотность пикселей или точек (на дюйм) устройства экрана в проекте Xamarin.iOS?
Я нашел несколько «решений», таких как тот, что заявил @JohnHardman в сообщении на форумах Xamarin (в котором используется код из XLabs, также предложенный в ответ @SKall в другом потоке SO, и, как указано на форуме, я не мог использовать, поскольку он «вероятно» вызовет отказ в Apple Store).
Другое решение, похоже, заключается в использовании замечательного Xamarin.Essentials. Тем не менее, они возвращают только Высокий, Ширина и Шкала. Но масштаб - это не то, что я ищу ...
Итак, знает ли кто-нибудь путь по этому, казалось бы, легкому / тривиальному пути? (почему это должно быть так сложно, такая простая задача?)
Привет, @LucasZ, на самом деле я хочу получить размер диагонали экрана устройства в дюймах, чтобы определить, меньше или больше устройство, чем «критическая» мера, которую я определяю ...
Вы можете получить диагональ экрана, сопоставив модель телефона с размером экрана устройства. Попробуйте использовать следующий код.
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 дюйма соответственно ...
Чтобы прочитать метод, который я использовал для окончательного получения плотности пикселей, пожалуйста, прочтите ниже раздел «Мой последний метод». Если вы хотите узнать, как я к этому пришел, продолжайте читать.
Итак, я провел дополнительное исследование и пришел к решению, которое меня устраивает. Я поделюсь этим для потомков.
Прежде всего, мне сказал @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
Мой последний метод был:
UIScreen.MainScreen.Bounds.Size
), чтобы получить размер диагонали экрана в пикселях (базовая математика Пифагора) и с его помощью вычислить плотность пикселей: pixels per inch = diagonal-size-in-pixels/diagonal-size-in-inches
.ПРИЛОЖЕНИЕ
Код для получения строки оборудования:
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);
Что ты хочешь делать ? Хотите ли вы определить модель устройства по ширине и высоте экрана?