【问题标题】:How to get points or pixels per inch of device using xamarin.iOS project?如何使用 xamarin.iOS 项目获取每英寸设备的点数或像素数?
【发布时间】:2019-02-14 14:24:29
【问题描述】:

问题就如标题所说:

如何在 Xamarin.iOS 项目中找出屏幕设备的像素或点密度(每英寸)?

我找到了一些“解决方案”,例如 the one stated by @JohnHardman in a post in Xamarin Forums(恰好使用了来自 XLabs 的代码,也在另一个 SO 线程中的 an answer by @SKall 中提出了建议,正如论坛中所述,我可以请勿使用,因为它“可能”会导致 Apple 商店 被拒绝)。

其他解决方案似乎是使用出色的 Xamarin.Essentials。然而,它们只返回 HighWidthScale。但规模不是我想要的......

那么,有没有人知道这条看似简单/微不足道的道路? (这么基本的任务为什么要这么复杂?)

【问题讨论】:

  • 你想做什么?是否要通过获取屏幕宽高来判断设备型号?
  • 嗨@LucasZ,实际上我想以英寸为单位获取设备的屏幕对角线测量值,以确定设备是否比我定义的“关键”测量值更小或更大......

标签: ios xamarin xamarin.ios


【解决方案1】:

根据判断设备的屏幕尺寸,获取手机型号即可得到屏幕对角线。尝试使用以下代码。

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 英寸......
【解决方案2】:

要直接阅读我用来最终获得像素密度的方法,请阅读下面的“我的最终方法”部分。如果您想了解我是如何做到这一点的,请继续阅读。


所以,我做了进一步的研究,并找到了一个令我满意的解决方案。在这里分享给后人。

首先,i was told by @ColeXXamarin 团队的成员)

没有用于获取每英寸设备的点数或像素的公共 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 threadXamarin 论坛 中,@LandLu(也是 Xamarin 团队的成员)指出我尚未another library:这个库也对hw.machine进行了神秘的查询。所以我决定向作者询问使用这种方法的风险和he answered

嗨@deczaloth,

这应该不是问题,因为 Apple 在提交时会检查每个应用程序以查看进行了哪些 API 调用,并且检索硬件字符串没有违规。我见过其他电话被拒绝但不是 hw.machine。希望能解答您的疑虑。问候


我的最终方法是:

  1. 通过使用a special library/nuGet/code检索硬件字符串获取详细的iOS模型(或参考附录中的代码)。
  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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 2013-01-15
    • 2014-11-03
    • 1970-01-01
    相关资源
    最近更新 更多