iOS retina display detection code not working
I have a problem with detecting retina displays on iOS devices开发者_开发问答. I'm using the following code which was recommended by various people:
BOOL isRetina()
{
UIScreen* s = [UIScreen mainScreen];
if ([s respondsToSelector:@selector(displayLinkWithTarget:selector:)] &&
[s respondsToSelector:@selector(scale)])
{
CGFloat scale = [s scale];
return scale == 2.0;
}
return NO;
}
The problem is that it compiles fine for deployment target iOS 4 and higher, but when I compile for iOS3.2 I get an "Incompatible types in initialization" error at the "scale = [s scale]" line because I'm trying to assign an id to a float. I couldn't find anything about that. Since everyone else seems to be using this approach I must be missing something really obvious here? Base SDK version is 4.3 with XCode 4 by the way.
Here are my BaseSDK/Deployment Target settings:
Update: I've solved it. Basically the problem was some XCode issue. To fix some other problem I had to uninstall and reinstall XCode. After that the behavior was gone.
In iOS 3.2, the symbol -[UIScreen scale]
is not defined and thus the compiler assumes it returns id
by default when you compile with iOS SDK 3.2. Hence the warning.
It's very important to understand the difference of SDK against which you compile and the deployment target. You generally want to compile against the latest SDK, but you set a deployment target of the minimum iOS version you want to support.
Here is the code I use that works as far back as 3.1 (I haven't tested earlier than that):
BOOL isRetina;
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2){
isRetina = YES;
} else {
isRetina = NO;
}
As pointed out by @DarkDust the problem isn't really your code (although the above should be simpler for you), it's that you are trying to compile for 3.2 and really you should just be setting your deployment target to 3.2 and still compiling using the latest SDK.
The difference is that when you compile for the older SDK it will fail to build because it knows it can't call that method (scale
) - even though it won't actually get to that line of code. But if you have set your deployment target correctly, you can use your code on 3.2 and not worry because you know the scale
method will never get called where it doesn't exist because you verified that it doesn't exist.
精彩评论