问题很简单,如标题中所述:
如何在 Xamarin.iOS 项目中找出屏幕设备的像素或点密度(每英寸)?
我发现了一些类似the one stated by @JohnHardman in a post in Xamarin Forums的“解决方案”(恰好使用了来自 XLabs 的代码,也在an answer by @SKall中在另一个SO线程中提出了建议,如我无法使用的论坛,因为它很可能在 Apple商店中引起拒绝。
其他解决方案似乎是使用出色的 Xamarin.Essentials 。但是,它们仅返回 High , Width 和 Scale 。但是规模不是我想要的...
那么,有人知道这条看似简单/琐碎的道路上的方法吗? (为什么这么复杂的基本任务如此?)
答案 0 :(得分:0)
通过使电话型号符合判断设备的屏幕尺寸,可以使屏幕对角线。尝试使用以下代码。
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;
}
}
答案 1 :(得分:0)
要直接阅读我最终用于获得像素密度的方法,请阅读“ 我的最终方法”部分下面的内容。如果您想阅读我的研究方法,请继续阅读。
因此,我进行了进一步的研究,并得出了令我满意的解决方案。我会在这里分享给后代。
首先,i was told by @ColeX( Xamarin 团队的成员)
没有用于获取设备每英寸点数或像素数的公共API 在iOS中。
因此需要一种不同的方法。首先,我认为我可以通过以像素为单位切换大小来获得屏幕大小,这可以在公共API中获得,但是正如我在@LucasZ的上面的评论中所写的那样,由于
iPad mini和iPad Air:它们都具有相同的高度(1024)和相同的比例(2x),但是由于PPI不同,因此它们分别为7.9英寸和9.7英寸...
然后我上面提到了带有 XLabs 的代码的选项。我首先在 Xamarin论坛的a thread中找到了这种方法,然后在a library of XLabs中独立地找到了这种方法。但是,这有违反苹果准则的评论的缺点。
很高兴,经过进一步的研究和更多的问答,在another thread的 Xamarin论坛中,@ LandLu(也是 Xamarin 小组成员)向我指出了这一点到another library:此库还向hw.machine
进行神秘查询。因此,我决定向作者询问使用这种方法和he answered的风险:
嗨@deczaloth,
这应该不成问题,因为Apple在提交应用程序时会检查每个应用程序,以查看进行了哪些API调用,并且检索硬件字符串并不违反。我看到有其他电话被拒绝,但hw.machine没有。希望能回答您的担忧。问候
我的最终方法是:
UIScreen.MainScreen.Bounds.Size
)获得以像素为单位的屏幕对角线尺寸(基本毕达哥拉斯数学),并由此计算像素密度:pixels per inch = diagonal-size-in-pixels/diagonal-size-in-inches
。 APENDIX
用于检索硬件字符串的代码:
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);