Click here to Skip to main content
15,867,308 members
Articles / Mobile Apps / iOS
Tip/Trick

iOS Tricks: Giving UISwitch's "on" Property Will/Did Change Observable Notifications

Rate me:
Please Sign up or sign in to vote.
4.11/5 (2 votes)
15 Jul 2014CPOL 18.5K   24   1   4
The UISwitch's UIControlEventValueChanged event is pretty useless if you'd like to get a notification only when the switch value actually changes.

Introduction

The UISwitch's UIControlEventValueChanged event is pretty useless if you'd like to get a notification only when the switch value actually changes. I have a solution that allows you to attach to the switch's "on" property's to get accurate change notifications.

Background

UISwitch inherits from UIControl which only has a UIControlEventValueChangedbefore value for you to determine if the value actually did change.

The More Better Class

The MySwitch class tweaks the UISwitch control by posting key/value change events when the control's value changes. It stores the previous value so it can determine when the on property actually changes.

MySwitch Interface

C++
@interface MySwitch : UISwitch
@end

MySwitch Implementation

C++
@implementation MySwitch
{
    BOOL _previousValue;
    BOOL _returnPreviousValue;
}

- (instancetype) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder: aDecoder];
    if (!self) return nil;
    
    _previousValue = self.isOn; // if constructed via a nib
    [self addTarget: self action: @selector(_didChange)
                forControlEvents: UIControlEventValueChanged];
    
    return self;
}

- (instancetype) initWithFrame: (CGRect) frame
{
    self = [super initWithFrame: frame];
    if (!self) return nil;
    
    [self addTarget: self action: @selector(_didChange)
                forControlEvents: UIControlEventValueChanged];
    
    return self;
}

- (BOOL) isOn
{
    return (_returnPreviousValue) // see [_didChange]
                        ? _previousValue
                        : [super isOn];
}

- (void) setOn: (BOOL) on animated: (BOOL) animated
{
    [super setOn: on animated: animated];

    _previousValue = on; // if set manually
}

- (void) _didChange
{
    BOOL isOn = self.isOn;
    
    if (isOn == _previousValue) return;
    
    _returnPreviousValue = true; // the will change might query 
                      // the current value. (isOn must then return the previous value) 
    [self willChangeValueForKey: @"on"];
    _returnPreviousValue = false;
    
    _previousValue = isOn;
    [self didChangeValueForKey:  @"on"];
}

@end

And Then Make Your Codez Sweet

All you need to do is add an observer to the MySwitch instance. The observer can even get the old and new values in the change parameter. (See NSKeyValueObservingOptionOld and NSKeyValueObservingOptionNew)

C++
- (void) viewDidLoad
{
    [super viewDidLoad];

    [self.switchView addObserver: self forKeyPath: @"on" 
                         options: NSKeyValueObservingOptionNew context: nil];
}

- (void) observeValueForKeyPath: (NSString *) 
keyPath ofObject: (id) object change: (NSDictionary *) change context: (void *) context
{
    if ([[change objectForKey: @"new"] boolValue])
    {
        self.textView.text = 
            [self.textView.text stringByAppendingString: @"changed to: ON\n"];
    }
    else
    {
        self.textView.text = 
            [self.textView.text stringByAppendingString: @"changed to: OFF\n"];
    }
}

- (void) toggleSwitch : (id) sender
{
    self.switchView.on = !self.switchView.on;
}

History

  • Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead FNB Connect
South Africa South Africa
iOS Technical Lead at FNB
-

Computers are really sweet. Aren't they?
Yup they are...

I've always loved writing tools and components...never been very interested in playing games....always wanted to be able to write them though.

And, yes. I'm still pretty annoyed they discontinued the Amiga computer.

Comments and Discussions

 
GeneralMy vote of 4 Pin
KarstenK16-Jul-14 5:12
mveKarstenK16-Jul-14 5:12 
GeneralRe: My vote of 4 Pin
Leslie Godwin17-Jul-14 1:26
Leslie Godwin17-Jul-14 1:26 
GeneralMy vote of 5 Pin
quinn.harly15-Jul-14 10:51
quinn.harly15-Jul-14 10:51 
GeneralRe: My vote of 5 Pin
Leslie Godwin15-Jul-14 22:54
Leslie Godwin15-Jul-14 22:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.