Home > Software engineering >  Using a Macro (Define) in an if/else statement ? Without redefined error
Using a Macro (Define) in an if/else statement ? Without redefined error

Time:10-20

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 }
  • Related