Reputation: 25697
I have a Constants.h
file in my app, where I #define
app-wide things for easy access later. I'm having a hard time, though, #define
ing based on iOS version. Here's what I've tried:
#ifdef __IPHONE_7_0
#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
#else
#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
#endif
Just because it says iOS 7 in there doesn't mean this is under NDA, O closers!
Which works fine - for iOS 7. When I run my app on iOS 6, however, the #define
is still the iOS 7 one - it seems as though the #ifdef
is never taken into account.
What can I do to fix this?
Upvotes: 3
Views: 12766
Reputation: 722
You should use #ifndef instead of #ifdef. Here is the code . I hope it will help you.
#ifndef __IPHONE_7_0
#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
#else
#define kHamburgerImage [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
#endif
Upvotes: 2
Reputation: 61
You can at least shorten your code by defining the iOS check as a macro.
#define IS_IOS7 [[UIDevice currentDevice].systemVersion hasPrefix:@"7"]
And then your new code is way more readable,
if (IS_IOS7) {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
} else {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
}
Upvotes: 6
Reputation: 318944
Instead of using compile-time checks, you need runtime checks. This means you can't use #define
. I suggest using a static variable that is initialized at runtime based on the version of iOS. Below is an example if you only need the value in a single file.
Some .m file:
static UIImage *kHamburgerImage = nil;
+ (void)initialize {
// This assumes you only support iOS 6 and later - adjust as needed
if ([[UIDevice currentDevice].systemVersion hasPrefix:@"6"]) {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
} else {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
}
}
Edit: Since these need to be globals, you should do this:
Constants.h:
extern UIImage *kHamburgerImage;
@interface Constants
@end
Constants.m:
UIImage *kHamburgerImage = nil;
@implementation Constants
+ (void)initialize {
// This assumes you only support iOS 6 and later - adjust as needed
if ([[UIDevice currentDevice].systemVersion hasPrefix:@"6"]) {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait.png"];
} else {
kHamburgerImage = [UIImage imageNamed:@"reveal_menu_icon_portrait_ios7.png"];
}
}
@end
But this suffers from a problem. Unless you take specific steps, accessing these globals could result in nil
pointers. They only get initialized if the class is actually referenced. I suggest that as the first line of your application:didFinishLaunchingWithOptions:
you do:
[Constants class];
This ensures the initializer is called and the constants are setup before you use them anywhere else in your code.
Upvotes: 7