【问题标题】:How to call [[UIScreen mainScreen] scale] in a universal app for the iphone and ipad如何在iphone和ipad的通用应用程序中调用[[UIScreen mainScreen] scale]
【发布时间】:2011-03-09 00:12:30
【问题描述】:

我正在制作一个可以在 ipad 和 iphone 上运行的通用应用程序。到目前为止一切顺利,但我刚刚将我的 SDK 更新到了 ios4,我想调用 [[UIScreen mainScreen] scale](scale 不在 3.2 sdk 中,ipad 还没有 ios4)。

我知道我可以调用 [[UIScreen mainScreen] respondsToSelector:@selector(scale)] 来看看我是否可以调用它,但我仍然需要函数调用(并且能够访问返回值)在我的代码中,以便它可以在 iphone 上运行。

已编辑:需要明确的是,我的问题是在为 3.2 SDK 构建时使用代码 [[UIScreen mainScreen] scale] 时出现错误。此错误是“分配中的不兼容类型”。所以我需要能够仍然为 4.0 SDK 调用此函数,但仍然为 3.2 SDK 构建项目。

【问题讨论】:

  • 在这种情况下,为什么不简单地编写自己的 -scale 呢?
  • 我其实想要api的返回值,我不想自己写。它实际上对我提出了一个更大的问题,即我将如何为其他列出但仍有适用于 ipad 和 iphone 的通用应用程序的新 api 做这样的事情。

标签: iphone ipad ios4


【解决方案1】:

好吧,你可以把对它的每个调用都包装在一个 if 语句中,就像这样:

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    //do scale stuff here
}

但更好的方法(不过这可能需要重组整个应用程序)是为 iPad 和 iPhone 设置单独的视图控制器。

要获得跨平台视图或其他设备的比例,您可以这样做:

CGFloat scale;
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    scale=[[UIScreen mainScreen] scale];
} else {
    scale=1; //only called on iPad.
}

为避免每次都输入此内容,您可以在 UIScreen 上声明一个类别,该类别在 -realScale 方法或其他方法中使用此代码。

所有这些方法都需要将基本 SDK 设置为 4.0(以便您可以访问 4.0 API)并将最低 iPhone 部署目标设置为 3.2(以便在 iPad 上运行)

【讨论】:

  • 这行不通,因为 [[UIScreen mainScreen] scale] 无法使用 3.2 SDK 构建,这是我的问题。
  • 我收到一个错误,而不仅仅是一个警告。但现在仔细看看这个错误,我想我知道如何解决它。错误是:“分配中的类型不兼容”。
  • 改一下,我不知道如何解决这个错误
  • 我正在使用类似的东西,但使用 [UIScreen mainScreen].scale,部署目标 = OS 3.0,它构建时没有警告。在我的 iPad 上运行良好(我没有其他设备
  • @Thomas:也感谢您的提醒,Tom H 也向我指出了这一点。
【解决方案2】:

啊。都错了。

  • 将“Base SDK”设置为 iPhone OS 4.0
  • 将“iPhone OS 部署目标”设置为 iPhone OS 3.2。

【讨论】:

  • 我在 5 小时前评论了另一个答案。
  • 谢谢 tc,但是是的,Tom H 也指出了这一点,他的反馈非常有帮助地指导我采用最简单的方法,所以我会将他的答案标记为正确。
【解决方案3】:

我最终在提出问题之前找到了解决方案,但我花了很长时间才弄清楚我决定发布我的问题和答案以防它帮助其他人。

这是我能够在 [UIScreen mainScreen] 上调用选择器比例并且仍然具有 ipad 版本构建的方式:

CGFloat screenScale;
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    //iphones with the latest SDK should end up in here (and also ipads when they are updated)
    NSMethodSignature * scaleSignature = [UIScreen instanceMethodSignatureForSelector:@selector(scale)];
    NSInvocation * scaleInvocation = [NSInvocation invocationWithMethodSignature:scaleSignature];
    [scaleInvocation setTarget:[UIScreen mainScreen]];
    [scaleInvocation setSelector:@selector(scale)];
    [scaleInvocation invoke];

    NSInteger returnLength = [[scaleInvocation methodSignature] methodReturnLength];
    //good memory management to check this in case anything changed in the future
    if (returnLength == sizeof(CGFloat)) {
        [scaleInvocation getReturnValue:&screenScale];
    } else {
        //default value
        screenScale = 1.0f;
    }
} else {
    //ipad (for now) and other SDK < 4.0 should come here
    screenScale = 1.0f;
}

【讨论】:

  • 我发布的内容有什么问题?它不能为 iPad 编译吗?如果它给你警告,你可以放心地忽略它们,但唯一更好的情况是编译器给出错误。
  • @Tom H:它确实给出了一个错误,“分配中的类型不兼容”。 @KennyTM:想提供一个简单的答案,那么我将非常感激。
  • 抱歉,您应该将 Xcode 中的基本 SDK 设置为 4.0,但 iPhone OS 的最低部署目标为 3.2。询问您是否需要有关如何执行此操作的帮助。
  • @Tom H:非常感谢您对我的指导。如果您使用将 Base SDK 设置为 4.0 并将 iPhone OS 部署目标设置为 3.2 的信息编辑您的答案,我会将您的答案标记为正确答案。
猜你喜欢
  • 1970-01-01
  • 2014-10-04
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
相关资源
最近更新 更多