49

After doing some reading, I've found that you can customize the text and color on a UISwitch control. I'm curious if these methods will cause problems trying to get my app approved and included in the App Store.

Sample code taken from iPhone Developer's Cookbook Sample Code:

// Custom font, color
switchView = [[UICustomSwitch alloc] initWithFrame:CGRectZero];
[switchView setCenter:CGPointMake(160.0f,260.0f)];
[switchView setLeftLabelText: @"Foo"];
[switchView setRightLabelText: @"Bar"];
[[switchView rightLabel] setFont:[UIFont fontWithName:@"Georgia" size:16.0f]];
[[switchView leftLabel] setFont:[UIFont fontWithName:@"Georgia" size:16.0f]];
[[switchView leftLabel] setTextColor:[UIColor yellowColor]]; 
pix0r
  • 31,139
  • 18
  • 86
  • 102

7 Answers7

40

this will not create problems with submitting to the app store. You are allowed to use custom controls or altered versions of the built in controls so long as you do not use any private (undocumented) APIs to build/alter these widgets.

zpesk
  • 4,343
  • 7
  • 39
  • 61
  • 3
    is there any proof/official statements to this that i can show to my managers? – Tomen Feb 17 '11 at 14:14
  • 16
    Nearly every app in the app store is proof of this. – lfalin Jul 29 '11 at 17:35
  • @lfalin, well that's a bit of an exaggeration. You don't actually know that approved apps on the store are actually customizing `UISwitch`, without the source code. Those apps could be customizing a `UIButton` or a `UISlider` or something else. The question was specifically about `UISwitch` and I think what the poster was getting at was whether or not some of the customization might use private APIs. I've also found examples out there for customizing controls that relied on undocumented features that changed in later OS versions, and thus broke. But, they were approved in my apps by Apple. – Nate May 20 '12 at 21:16
  • 1
    @Nate, I wasn't referring to the OP. This answer stated "You are allowed to use custom controls or altered versions of the built in controls", then Tomen asked if there was proof of that. My response was in reply to Tomen's comment and the answer. – lfalin May 21 '12 at 14:18
  • 1
    @Tomen if it is proof enough, I had an app rejected for using a private API for turning the UISwitch color to orange (like airplane mode) instead of the standard blue – Dan F Aug 10 '12 at 13:58
  • @Nate sounds like you don't know about class-dump :) –  Sep 22 '12 at 19:24
  • 1
    @H2CO3, sounds like you don't know about the SO search field :). Paste `user:119114 class-dump` into the search field, and you'll see that I've mentioned class-dump in at least 5 answers. That doesn't change the issue. Class-dump just lets you back out some of the code. Did Ifalin run class-dump (which requires decrypting archives) on nearly every app in the store? I think not. He/she is making the implicit statement that you can just *look* at all the apps with custom-looking controls, as *proof* that you can modify UISwitch, and that's not true (not proof). BTW, I know about IDA, too. – Nate Sep 24 '12 at 20:56
16

You might enjoy my implementation of a custom switch (open source and free to use)... it allows setting the switch to display any text, or easily subclass it to draw your own custom images in the track.... http://osiris.laya.com/projects/rcswitch/

This switch makes it easy to draw an image instead of text: subclass the main switch class and override the draw method like this, and your image will be automatically animated:

- (void)drawUnderlayersInRect:(CGRect)aRect withOffset:(float)offset inTrackWidth:(float)trackWidth
{
    [onImage drawAtPoint:CGPointMake(floorf(aRect.origin.x + 13 + (offset - trackWidth)), floorf((self.bounds.size.height - onImage.size.height) / 2.0))];
    [offImage drawAtPoint:CGPointMake(floorf(aRect.origin.x + 15.0 + (offset + trackWidth)), ceilf((self.bounds.size.height - offImage.size.height) / 2.0))];
}
Robert Chin
  • 161
  • 1
  • 4
  • By the way, for those that downloaded the original 1.0 version of RCSwitch, you might want to consider updating to the 1.1 version I posted. There appear to be some drawing bugs with stretchable images that only appear on the iPhone (they appear to be fixed on the iPad so perhaps they are fixed in iPhone OS 3.2). This update works around these issues. – Robert Chin May 08 '10 at 06:26
1

No need to UISwitch subclass at all. A fairly simple solution which I Implemented is subclased UIView and on touch event toggled between two images (ON/OFF) with slide transition thats all.

Regards Dhanesh

infiniteLoop
  • 2,135
  • 1
  • 25
  • 29
1

i just created this view, and saw you question

hope this helps

the .h file:

#import <UIKit/UIKit.h>

@interface EDSwitch : UIView
{
    UIButton* onButton,*offButton;
    UIImageView* bg;
}

- (id)initWithText:(NSString*)on andText:(NSString*)off andDelegate:(id)delegate andOnSelector:(SEL)onSelector andOffSelector:(SEL)offSelector andBackgroundImage:(UIImage*)bgImage andStartingValue:(BOOL)b;

@end

and the .m file:

#import "EDSwitch.h"

@implementation EDSwitch

- (id)initWithText:(NSString*)on andText:(NSString*)off andDelegate:(id)delegate     andOnSelector:(SEL)onSelector andOffSelector:(SEL)offSelector andBackgroundImage:     (UIImage*)bgImage andStartingValue:(BOOL)b
{
self = [super initWithFrame:CGRectZero];
if (self) {
    UILabel* onLabel = [[UILabel alloc] initWithFrame:CGRectMake(2, 8, 50, 20)];
    onLabel.text = on ;
    onLabel.tag = 1;
    onLabel.font = [UIFont fontWithName:kCalibri size:15];
    onLabel.textAlignment = UITextAlignmentCenter;
    onLabel.textColor = [UIColor colorFromHexString:@"#009dd0"];
    onLabel.backgroundColor = [UIColor clearColor];
    [onLabel sizeToFit];
    [onLabel setWidth:onLabel.frame.size.width + 4];


    UILabel* offLabel = [[UILabel alloc] initWithFrame:CGRectMake(2, 8, 50, 20)];
    offLabel.text = off ;
    offLabel.tag = 1;
    offLabel.textAlignment = UITextAlignmentCenter;
    offLabel.font = [UIFont fontWithName:kCalibri size:15];
    offLabel.textColor = [UIColor colorFromHexString:@"#009dd0"];
    offLabel.backgroundColor = [UIColor clearColor];
    [offLabel sizeToFit];
    [offLabel setWidth:offLabel.frame.size.width + 4];

    float high = MAX([offLabel.text sizeWithFont:offLabel.font].width,[onLabel.text sizeWithFont:onLabel.font].width) + 10;

    onButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [onButton addTarget:self action:@selector(toggled:) forControlEvents:UIControlEventTouchUpInside];
    [onButton addTarget:delegate action:onSelector forControlEvents:UIControlEventTouchUpInside];
    offButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [offButton addTarget:self action:@selector(toggled:) forControlEvents:UIControlEventTouchUpInside];
    [offButton addTarget:delegate action:offSelector forControlEvents:UIControlEventTouchUpInside];

    [onButton setWidth:high];
    [onButton setX:0];
    [onButton addSubview:onLabel];
    [onLabel setWidth:high];
    [onLabel setX:0];

    [offButton setWidth:high];
    [offButton addSubview:offLabel];
    [offButton setX:high];
    [offLabel setWidth:high];
    [offLabel setX:0];

    bg = [[UIImageView alloc] initWithImage:bgImage];

    self.frame = CGRectMake(200, 200 , (high*2), 34);
    self.layer.borderColor = [[[UIColor colorFromHexString:@"#009dd0"] colorWithAlphaComponent:0.5] CGColor];
    self.layer.borderWidth = 0.5;
    self.layer.cornerRadius = 5;
    [self setX:[UIApplication sharedApplication].keyWindow.frame.size.width - self.frame.size.width - 8];

    [self addSubview:bg];

    [bg setWidth:[self getWidth]];
    [bg setHeight:[self getHeight]];

    [self addSubview:onButton];
    [self addSubview:offButton];

    [onButton setHeight:[self getHeight]];
    [offButton setHeight:[self getHeight]];

    if(b){
        [onButton setBackgroundColor:[UIColor clearColor]];
        [offButton setBackgroundColor:[UIColor whiteColor]];
    }
    else{
        [onButton setBackgroundColor:[UIColor whiteColor]];
        [offButton setBackgroundColor:[UIColor clearColor]];
    }
}
return self;
}

-(void)toggled:(UIButton*)sender{
if(sender == onButton){
    UILabel* l = (UILabel*)[onButton viewWithTag:1];
    l.textColor = [UIColor grayColor];
    [onButton setBackgroundColor:[UIColor clearColor]];
    l = (UILabel*)[offButton viewWithTag:1];
    l.textColor = [UIColor colorFromHexString:@"#009dd0"];
    [offButton setBackgroundColor:[UIColor whiteColor]];

}
else{
    UILabel* l = (UILabel*)[offButton viewWithTag:1];
    l.textColor = [UIColor grayColor];
    [offButton setBackgroundColor:[UIColor clearColor]];
    l = (UILabel*)[onButton viewWithTag:1];
    l.textColor = [UIColor colorFromHexString:@"#009dd0"];
    [onButton setBackgroundColor:[UIColor whiteColor]];
}
}

@end

usage:

    [[UIApplication sharedApplication].keyWindow addSubview:[[EDSwitch alloc] initWithText:@"aksdjaksdjh" andText:@"dasjdsaj" andDelegate:self andOnSelector:@selector(logon) andOffSelector:@selector(logoff) andBackgroundImage:[UIImage imageNamed:@"toggleBottom.png"] andStartingValue:YES]];

live long and prosper,

eiran

eiran
  • 1,378
  • 15
  • 16
0

From Apple documentation :-

You use the UISwitch class to create and manage the On/Off buttons you see, for example, in the preferences (Settings) for such services as Airplane Mode. These objects are known as switches.

The UISwitch class declares a property and a method to control its on/off state. As with UISlider, when the user manipulates the switch control (“flips” it) a UIControlEventValueChanged event is generated, which results in the control (if properly configured) sending an action message.

The UISwitch class is not customisable.

Apple is saying that they aren't customisable, which might mean having your app rejected.

Tim Post
  • 33,371
  • 15
  • 110
  • 174
0

In the Apple Human Interface Guidelines, in the Switch documentation, Apple state:

Use a switch in a table row to give users two simple, diametrically opposed choices that determine the state of something, such as yes/no or on/off. Use a predictable pair of values so that users don’t have to slide the control to discover what the other value is.

So, yes, it's fine to change the text so long as you use a predictable pair of values (like yes/no).

Nic Rodgers
  • 283
  • 1
  • 3
  • 7
-30

This WILL cause issues with your app approval. ask me how I know :P

I just got a nasty note today from Apple. We are in the process of looking for an alternative.