Custom UISwitch Text

While working on a project for a client, I encountered an issue with customizing UISwitches. The project involved updating a previous built application to make it iOS5 compatible. Everything was going well until I tried to use the code the previous programmer provided. When building the file for iOS 4, the following code worked fine.

((UILabel *)[[[[[[switchView subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:0]).text = @"M";
((UILabel *)[[[[[[switchView subviews] lastObject] subviews] objectAtIndex:2] subviews] objectAtIndex:1]).text = @"F";

However, I found that building for iOS5 caused my application to crash when I was attempting to customize the label. I decided to investigate, and used a technique to loop through all the views of an object and spit out the class types. I ran the test for both iOS4 and iOS5 with the following results:

iOS 4
<_UISwitchSlider: 0x5a3dc20; frame = (0 0; 94 27); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x5a3dca0>>
<UIImageView: 0x5a3e040; frame = (0 0; 94 27); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a3e070>>
<UIImageView: 0x5a3e0c0; frame = (0 0; 94 27); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a3e0f0>>
<UIView: 0x5a3e180; frame = (3 0; 88 27); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a3e1b0>>
<UILabel: 0x5a3e240; frame = (-40 0; 24 27); text = 'ON'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a3e2b0>>
<UILabel: 0x5a36450; frame = (48 0; 32 27); text = 'OFF'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a364c0>>
<UIImageView: 0x5a3e120; frame = (-2 0; 45 27); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a3e150>>
 
iOS 5
<_UISwitchInternalView: 0x19bcf0; frame = (-1 0; 79 27); layer = <CALayer: 0x19bd60>>
<UIImageView: 0x19bd90; frame = (1 0; 77 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x19bdd0>>
<UIView: 0x19be00; frame = (1 0; 77 27); clipsToBounds = YES; alpha = 0; layer = <CALayer: 0x19be30>>
<UIImageView: 0x19bee0; frame = (-52 0; 79 27); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x19bf20>>
<UIImageView: 0x19bf80; frame = (-52 0; 131 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x19bfc0>>
<UIImageView: 0x19bff0; frame = (-1 0; 29 27); userInteractionEnabled = NO; layer = <CALayer: 0x19c030>>

As you can see from the output above, iOS4 provides a UILabel that can be accessed. The previous programmer’s code targeted this specific subview and set the label text. However, in iOS5 you’ll see that the UILabel is non-existent. When the code runs and attempts to use a UILabel, it finds none and crashes.

I’m speculating, but it would appear that iOS5 is using image views to render the text on a UISwitch. The only way to customize the UISwitch would be to build your own view to use.

Luckily, I found a set of classes that allows you to do just that. The class is called DCRoundSwitch and was written by Domestic Cat Software. The class was super easy use. Simply import the header file and instantiate a DCRoundSwitch instead of a UISwitch. You then set the ‘onText’ and ‘offText’ properties of the switch to customize the text displayed.

DCRoundSwitch *switchView = [[DCRoundSwitch alloc] init];
switchView.onText = @"M";
switchView.offText = @"F";

This is obviously much better than trying to target a specific subview which may or may not exist. If you’re looking to build round UISwitches that need to be customized, you should definitely download that class.

Their github account has a project file you can download and play with.

Warning: After compiling an old project into iOS5 using armv7 architecture, be sure to go back and extensively test your application to see if problems like this occur. The above problem may have been caused by not including the armv6 architecture when I was running my tests, but it goes to show you that it’s important to test your applications completely after a new SDK version comes out.

Hopefully this is helpful for some of you. It’s my first technical post, and was pretty fun to write, so I’ll probably post more in the future. I’d love to hear what problems you’ve run into with iOS5, so if you’ve hit any bugs, tell me about them in the comments.

About The Author

Andrew is a mobile application developer who has crossed over from the web development world. When not chugging Diet Mountain Dew and coding up apps, he enjoys watching hockey and spending time with his fiancee and puppy.

0 Comments