user2813740
user2813740

Reputation: 337

Macro not working as required in Objective-C

I have one macro, very simple one but I do not understand where is the problem? I got error:

"Expected ; after expression"

This is a macro definition:

#define SEGCONTROL (itemArray, segmentedControl)      \
segmentedControl = [[SuperSegmentedControll alloc] initWithItems:itemArray];                                        \
segmentedControl.frame = CGRectMake(0, 0, 60, 28);     \
segmentedControl.layer.cornerRadius = 05;              \
[segmentedControl setTintColor:[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:102.0/255.0 alpha:1]];                  \
segmentedControl.backgroundColor = [UIColor colorWithRed:19.0/255.0 green:62.0/255.0 blue:137.0/255.0 alpha:1];              [segmentedControl setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateNormal];                                \
[segmentedControl setTitleTextAttributes:               @{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateSelected]; \

I am calling as below:

 NSArray *itemArray = [NSArray arrayWithObjects: @"Save", nil];
 SuperSegmentedControll *segmentedControl;
 SEGCONTROL(itemArray, segmentedControl);

I would like to create macro as similar code which is used at many places. For save, cancel ETC.

Upvotes: 1

Views: 188

Answers (1)

Steve Wilford
Steve Wilford

Reputation: 9012

The reason that this is failing is because there is a space between the #define macro name SEGCONTROL and the parameter list (itemArray, segmentedControl). This is essentially defining SEGCONTROL as (itemArray, segmentedControl) rather than the code snippet. To resolve the issue simply remove the space after SEGCONTROL

#define SEGCONTROL(itemArray, segmentedControl) \ ...

However I would strongly recommend against using this approach, instead have a method on your SuperSegmentedControll class (which in turn should probably have a single L and a more descriptive name) that sets up the control. This way you will get better compiler checks. Something like this:

@implementation SuperSegmentedControl

- (instancetype)initWithItems:(NSArray *)items {
    self = [super initWithItems:items];
    if (self) {
        self.frame = CGRectMake(0, 0, 60, 28);
        self.layer.cornerRadius = 05;
        [self setTintColor:[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:102.0/255.0 alpha:1]];
        self.backgroundColor = [UIColor colorWithRed:19.0/255.0 green:62.0/255.0 blue:137.0/255.0 alpha:1];
        [self setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateNormal];
        [self setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]} forState:UIControlStateSelected];
    }
    return self;
}

@end

Which would be used as follows:

NSArray *itemArray = [NSArray arrayWithObjects: @"Save", nil];
SuperSegmentedControl *segmentedControl = [[SuperSegmentedControl alloc] initWithItems:itemArray];

Upvotes: 4

Related Questions