如何在iphone和ipad的通用应用程序中调用[[UIScreen mainScreen]scale]

如何在iphone和ipad的通用应用程序中调用[[UIScreen mainScreen]scale],iphone,ipad,ios4,Iphone,Ipad,Ios4,我正在制作一个通用的应用程序,可以在ipad和iphone上运行。到目前为止还不错,但我刚刚将我的SDK更新为ios4,我想调用[[UIScreen mainScreen]scale](scale不在3.2 SDK中,ipad还没有ios4) 我知道我可以调用[[UIScreen mainScreen]respondsToSelector:@selector(scale)]来确定我是否可以调用它,但我仍然需要在代码中包含函数调用(并能够访问返回值),以便它可以在iphone上运行 已编辑:明确地

我正在制作一个通用的应用程序,可以在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进行项目构建。

好吧,您可以将对它的每个调用都封装在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上运行)

好吧,您可以将对它的每个调用都封装在一个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 Main Screen]上调用选择器刻度的方式,并且仍然拥有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;
}
CGFloat屏幕比例;
如果([[UIScreen Main Screen]响应选择器:@选择器(比例)]){
//带有最新SDK的iPhone应该在这里结束(更新后的iPad也是如此)
NSMethodSignature*scaleSignature=[UIScreen instanceMethodSignatureForSelector:@selector(scale)];
NSInvocation*scaleInvocation=[NSInvocation invocationWithMethodSignature:scaleSignature];
[缩放位置设置目标:[UIScreen Main Screen]];
[缩放位置设置选择器:@选择器(缩放)];
[scaleInvocation调用];
NSInteger returnLength=[[scaleInvocation methodSignature]methodReturnLength];
//良好的内存管理,以防将来发生任何更改
if(returnLength==sizeof(CGFloat)){
[scaleInvocation getReturnValue:&screenScale];
}否则{
//默认值
屏幕比例=1.0f;
}
}否则{
//ipad(目前)和其他SDK<4.0的软件应该到这里来
屏幕比例=1.0f;
}

在提出问题之前,我最终找到了解决方案,但我花了很长时间才意识到,我决定发布我的问题和答案,以防对其他人有所帮助

这就是我能够在[UIScreen Main Screen]上调用选择器刻度的方式,并且仍然拥有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;
}
CGFloat屏幕比例;
如果([[UIScreen Main Screen]响应选择器:@选择器(比例)]){
//带有最新SDK的iPhone应该在这里结束(更新后的iPad也是如此)
NSMethodSignature*scaleSignature=[UIScreen instanceMethodSignatureForSelector:@selector(scale)];
NSInvocation*scaleInvocation=[NSInvocation invocationWithMethodSignature:scaleSignature];
[缩放位置设置目标:[UIScreen Main Screen]];
[缩放位置设置选择器:@选择器(缩放)];
[scaleInvocation调用];
NSInteger returnLength=[[scaleInvocation methodSignature]methodReturnLength];
//良好的内存管理,以防将来发生任何更改
if(returnLength==sizeof(CGFloat)){
[scaleInvocation getReturnValue:&screenScale];
}否则{
//默认值
屏幕比例=1.0f;
}
}否则{
//ipad(目前)和其他SDK<4.0的软件应该到这里来
屏幕比例=1.0f;
}
Argh。完全错了

  • 将“基本SDK”设置为iPhone OS 4.0
  • 将“iPhone OS部署目标”设置为iPhone OS 3.2
    • 啊。完全错了

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

      在这种情况下,为什么不直接编写自己的-scale?我实际上想要api的返回值,我不想只编写自己的。事实上,这给我提出了一个更大的问题,我将如何为其他新的api做类似的事情,这些api已经上市,但仍然有一个适用于ipad和iphone的通用应用程序。在这种情况下,为什么不简单地编写你自己的-scale?我实际上想要api的返回值,我不想只编写我自己的。事实上,这给我提出了一个更大的问题:我将如何为其他新api做类似的事情,这些api已经上市,但仍然有一个针对ipad和iphone的通用应用程序。我发布的东西有什么问题?它不是为iPad编译的吗?如果它向您发出警告,您可以安全地忽略它们,但最好是编译器给出错误。@Tom H:它确实给出错误,“赋值中的不兼容类型”@肯尼特:如果你想用一个简单的答案来帮助我,我将非常感激