How to call [[UIScreen mainScreen] scale] in a universal app for the iphone and ipad

浪尽此生 提交于 2019-12-30 05:28:05

问题


I'm making a universal app that will run on both the ipad and the iphone. So far so good, but I have just updated my SDK to ios4 and am wanting to call [[UIScreen mainScreen] scale] (scale is not in the 3.2 sdk and the ipad doesn't have ios4 yet).

I know that I can call [[UIScreen mainScreen] respondsToSelector:@selector(scale)] to find out if I can call it, but I still need to have the function call (and be able to access the return value) in my code so that it can run on the iphone.

EDITED: To be clear, my problem is that there is an error when using the code [[UIScreen mainScreen] scale] when building for 3.2 SDK. This error is "Incompatible types in assignment". So I need to be able to still call this function for 4.0 SDK but still have the project build for 3.2 SDK.


回答1:


Well, you could just wrap every call to it in an if statement, like so:

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

But a better way (which might require restructuring your whole app, though) is to have separate view controllers for iPad and iPhone.

To get the scale of the device for a cross platform view or something, you could do like this:

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

To avoid typing this every time, you could declare a category on UIScreen, which uses this code inside a -realScale method or something.

All of these methods require setting the base SDK to 4.0 (so that you can access the 4.0 APIs) and the minimum iPhone deployment target to 3.2 (so it will run on iPad)




回答2:


Argh. All wrong.

  • Set the "Base SDK" to iPhone OS 4.0
  • Set the "iPhone OS Deployment Target" to iPhone OS 3.2.



回答3:


I ended up finding a solution before asking my question, but it took me forever to figure it out that I decided to post my question and answer in case it helped others.

This is the way that I was able to call the selector scale on the [UIScreen mainScreen] and still have the ipad version build:

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;
}


来源:https://stackoverflow.com/questions/3130420/how-to-call-uiscreen-mainscreen-scale-in-a-universal-app-for-the-iphone-and

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!