要直接阅读我用来最终获得像素密度的方法,请阅读下面的“我的最终方法”部分。如果您想了解我是如何做到这一点的,请继续阅读。
所以,我做了进一步的研究,并找到了一个令我满意的解决方案。在这里分享给后人。
首先,i was told by @ColeX(Xamarin 团队的成员)
没有用于获取每英寸设备的点数或像素的公共 API
在 iOS 中。
因此需要一种不同的方法。首先,我认为我可以通过 Switch-Casing 像素大小来获得屏幕大小,这可以在公共 API 中获得,但正如我在上面对@LucasZ 的评论中所写的那样,这将是不精确的,因为
iPad mini 和 iPad Air:它们都具有相同的高度 (1024) 和相同的比例 (2x),但由于 PPI 不同,因此它们分别为 7.9 英寸和 9.7 英寸...
然后是我上面提到的 XLabs 的代码选项。这种方法我首先在 Xamarin 论坛 的a thread 中找到,然后在a library of XLabs 中独立找到。然而,这有关于违反 Apple 准则的评论的缺点......
令人高兴的是,经过进一步的研究和更多的问答,在another thread 的 Xamarin 论坛 中,@LandLu(也是 Xamarin 团队的成员)指出我尚未another library:这个库也对hw.machine进行了神秘的查询。所以我决定向作者询问使用这种方法的风险和he answered:
嗨@deczaloth,
这应该不是问题,因为 Apple 在提交时会检查每个应用程序以查看进行了哪些 API 调用,并且检索硬件字符串没有违规。我见过其他电话被拒绝但不是 hw.machine。希望能解答您的疑虑。问候
我的最终方法是:
- 通过使用a special library/nuGet/code检索硬件字符串获取详细的iOS模型(或参考附录中的代码)。
- Switch-Case 将上一步得到的详细模型与以英寸为单位的屏幕尺寸的公开信息(此信息是公开的,来源很多,例如臭名昭著的iosres.com)。
- 使用公共 API (
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);