I am aware this is not a good way of coding, however I am just in the process of making the game I am working on from Obj-C
to Swift
, however I am trying to get it to run correctly on my devices just so I can go back and reference everything.
So, this is effectively a temporary measure! I have a couple of Macro's defined,
#define BTNNUMBER_W 60
#define BTNNUMBER_H 60
They are referenced in the code, in an area where I really cannot split if/else statements, so wanted to effectively debug using;
if(IS_IPHONE_OLD)
{
#define BTNNUMBER_W 60
#define BTNNUMBER_H 60
}
else if (IS_IPHONE_5)
{
#define BTNNUMBER_W 60
#define BTNNUMBER_H 60
}
else if (IS_IPHONE_6_6S_6P_6SP_7_8)
{
#define BTNNUMBER_W 30
#define BTNNUMBER_H 30
NSLog(@"iPhone 6 to 8");
}
else if (IS_IPHONE_7P_8P)
{
#define BTNNUMBER_W 60
#define BTNNUMBER_H 60
NSLog(@"iPhone 7P to 8P");
}
else if (IS_IPHONE_X)
{
#define BTNNUMBER_W 110
#define BTNNUMBER_H 110
}
As already said, it's really just to 'get it working' again, whilst I re-do it all, but any pointers would be much obliged!
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
#define IDIOM UI_USER_INTERFACE_IDIOM()
#define IPAD UIUserInterfaceIdiomPad
#define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
#define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
#define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
#define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
#define IS_IPHONE_OLD (IS_IPHONE && SCREEN_MAX_LENGTH == 480.0)
#define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
#define IS_IPHONE_6_6S_6P_6SP_7_8 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
#define IS_IPHONE_7P_8P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)
#define IS_IPHONE_X (IS_IPHONE && SCREEN_MAX_LENGTH == 812.0)
CodePudding user response:
In C and Objective-C, use the preprocessor's #if
rather than than the programming language's if
:
#if IS_IPHONE_OLD || IS_IPHONE_5
#define BTNNUMBER_W 60
#define BTNNUMBER_H 60
#elif IS_IPHONE_6_6S_6P_6SP_7_8
#define BTNNUMBER_W 30
#define BTNNUMBER_H 30
// …
#endif
However this will not work because your IS_IPHONE_OLD
etc. are not compile-time constants (nor can they be, since the same app can be run on multiple phones). The pre-processor does simple text-replacement, and all of it takes place before any of the code is even parsed (hence pre-processor).
You cannot affect pre-processor macros at runtime, but you can only know the screen size at runtime…
Instead, switch your macros to variables of the same name:
CGFloat BTNNUMBER_W;
CGFloat BTNNUMBER_H;
And then in some function that is run before they are used, assign their values:
if (IS_IPHONE_OLD || IS_IPHONE_5) {
BTNNUMBER_W = 60;
BTNNUMBER_H = 60;
} // …
Alternatively, name your variable something nicer and then:
#define BTNNUMBER_W ([[AppDelegate instance] buttonNumberWidth])
In Swift, use computed properties:
static var buttonNumberWidth: CGFloat {
let screenWidth = UIScreen.main.bounds.size.width
if screenWidth <= 480 {
return 30
} // …
}
static var buttonNumberHeight: CGFloat { buttonNumberWidth }