This sounds trivial but I\'m noticing some weirdness. I\'ve wired up a handler for the Value Changed event of a UISwitch. What I would expect is that each time the hand
-(void) createSwitch
{
self.searchExistSearchNewSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0,0,0,0)];
[self.searchExistSearchNewSwitch addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:self.searchExistSearchNewSwitch];
}
- (void)switchValueChanged:(UISwitch *)theSwitch
{
BOOL flag = theSwitch.isOn;
}
Each press you make doesn't immediately toggle the switch on/off. If the switch is in the off position, you can get a couple of presses in before it animates to the on position. Each of these presses are interpreted as "turn the switch on", since it is not considered "on" until the animation has completed. You get a "valueChanged" callback for each press despite the fact that the value hasn't actually changed yet.
Get state of switch in handler:
- (void)valueChanged:(UISwitch *)theSwitch {
BOOL flag = theSwitch.on;
}
My problem was a stupid one... I was expecting the enabled
value to change, but obviously that isn't the correct value to inspect upon the toggle of the switch, the on
or isOn
is the correct thing to use.
When you toggle the switch off/On the "value changed" has been called.So you can detecting a change in switch by calling method on valueChanged.
Here's a solution that works for me. It also sends a property "will/did change" notification when the switch is changed. The event also functions correctly in that the before and after values are maintained correctly.
@interface MySwitch : UISwitch
@end
@implementation MySwitch
{
BOOL _previousValue;
BOOL _returnPreviousValue;
}
- (instancetype) initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder: aDecoder];
if (!self) return nil;
_previousValue = self.isOn;
[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)
? _previousValue
: [super isOn];
}
- (void) setOn:(BOOL) on animated: (BOOL) animated
{
[super setOn: on animated: animated];
_previousValue = on;
}
- (void) _didChange
{
BOOL isOn = self.isOn;
if (isOn == _previousValue) return;
_returnPreviousValue = true;
[self willChangeValueForKey: @"on"];
_returnPreviousValue = false;
_previousValue = isOn;
[self didChangeValueForKey: @"on"];
}
@end