[ACCEPTED]-Detecting a change in UISwitch-uiswitch
-(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;
}
0
In iOS 11 a new UISwitch bug was introduced so I don't recommend 3 subscribing to value changed events. Otherwise 2 your callback will be triggered every time 1 UISwitch
's isOn
attribute changes programmatically.
Instead:
- Subscribe for touch up inside event:
let switch = UISwitch()
switch.addTarget(self, action: #selector(onSwitchValueChanged), for: .valueChanged)
- Implement the callback method:
func onSwitchValueChanged(_ switch: UISwitch) {
}
- And now when you programmatically change
isOn
value, it won't triggeronSwitchValueChanged
method.
switch.isOn = !switch.isOn // 'onSwitchValueChanged' is not triggered
Get state of switch in handler:
- (void)valueChanged:(UISwitch *)theSwitch {
BOOL flag = theSwitch.on;
}
0
Each press you make doesn't immediately 9 toggle the switch on/off. If the switch 8 is in the off position, you can get a couple 7 of presses in before it animates to the 6 on position. Each of these presses are interpreted 5 as "turn the switch on", since it is not 4 considered "on" until the animation has 3 completed. You get a "valueChanged" callback 2 for each press despite the fact that the 1 value hasn't actually changed yet.
Here's a solution that works for me. It 4 also sends a property "will/did change" notification 3 when the switch is changed. The event also 2 functions correctly in that the before and 1 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
Log the last state so you can tell if its 2 changed state or has been triggered with 1 the same state.
When you toggle the switch off/On the "value 3 changed" has been called.So you can detecting 2 a change in switch by calling method on 1 valueChanged.
My problem was a stupid one... I was expecting 4 the enabled
value to change, but obviously that 3 isn't the correct value to inspect upon 2 the toggle of the switch, the on
or isOn
is the 1 correct thing to use.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.