Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UISegmentedControl setImage: Bug in iOS7

I have a UISegmentedControl in my app. As of iOS7 GM, the images I use are not showing up when run on iOS7 devices. Anyone else having this problem?

Here's what it looks like in iOS6.1 and earlieriOS6-ScreenShot .

and here is what it looks like in iOS7iOS7-ScreenShot .

Here is the code:

self.theSegmentedControl.frame = CGRectMake(self.theSegmentedControl.frame.origin.x, self.theSegmentedControl.frame.origin.y, 320, 35);
[self.theSegmentedControl setBackgroundImage:[UIImage imageNamed:@"img_toggleInactive"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[self.theSegmentedControl setImage:[UIImage imageNamed:@"btn_onceActive"] forSegmentAtIndex:0];
[self.theSegmentedControl setImage:[UIImage imageNamed:@"btn_recurringInactive"] forSegmentAtIndex:1];
[self.theSegmentedControl setImage:[UIImage imageNamed:@"btn_scheduledInactive"] forSegmentAtIndex:2];
[self.theSegmentedControl setDividerImage:[UIImage imageNamed:@"separator"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];

Has anyone found a workaround to this?

like image 629
kevmalek Avatar asked Sep 11 '25 04:09

kevmalek


2 Answers

Woohoo! Here's the workaround:

//Add clear color to mask any bits of a selection state that the object might show around the images
self.theSegmentedControl.tintColor = [UIColor clearColor];

UIImage *onceActive;
UIImage *recurringActive;
UIImage *scheduledActive;
UIImage *separator;

//Setting imageWithRenderingMode: to imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal for iOS7 is key
if ([UIImage instancesRespondToSelector:@selector(imageWithRenderingMode:)]) {
    onceActive = [[UIImage imageNamed:@"btn_onceActive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    recurringActive = [[UIImage imageNamed:@"btn_recurringInactive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    scheduledActive = [[UIImage imageNamed:@"btn_scheduledInactive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    separator = [[UIImage imageNamed:@"separator"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

}
else {
    onceActive = [UIImage imageNamed:@"btn_onceActive"];
    recurringActive = [UIImage imageNamed:@"btn_recurringInactive"];
    scheduledActive = [UIImage imageNamed:@"btn_scheduledInactive"];
    separator = [UIImage imageNamed:@"separator"];
}


[self.theSegmentedControl setImage:onceActive forSegmentAtIndex:0];
[self.theSegmentedControl setImage:recurringActive forSegmentAtIndex:1];
[self.theSegmentedControl setImage:scheduledActive forSegmentAtIndex:2];
[self.theSegmentedControl setDividerImage:separator forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
like image 113
kevmalek Avatar answered Sep 12 '25 17:09

kevmalek


UPDATE for Xcode 6/iOS 8

Now you can do it in Interface builder

Just add the image file in the asset catalog and set its "render as" original image instead of default

Xcode 5

The new UISegmented control uses the tint color to tint the images using the template mode. You will need to render these images as original and not templates.

As suggested in the comments do this:

UIImage* onceActive = [UIImage imageNamed:@"btn_onceActive"];
if (IOS_7_MACRO)
    onceActive = [onceActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[self.theSegmentedControl setImage:onceActive forSegmentAtIndex:0];
like image 28
João Nunes Avatar answered Sep 12 '25 17:09

João Nunes