iOS7 UISwitch its Event ValueChanged: Calling continuously is this Bug or what..?
Solution 1
I got many user that facing same issue so may be this is bug of UISwitch
so i found just now for temporary solution of it. I Found one gitHub
custom KLSwitch
use this for now hope apple will fix this in next update of xCode:-
https://github.com/KieranLafferty/KLSwitch
Solution 2
Please see the following code:
-(void)viewDidLoad
{
[super viewDidLoad];
UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(130, 235, 0, 0)];
[mySwitch addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:mySwitch];
}
- (void)changeSwitch:(id)sender{
if([sender isOn]){
NSLog(@"Switch is ON");
} else{
NSLog(@"Switch is OFF");
}
}
Solution 3
You can use the UISwitch
's .selected
property to make sure your code only executes once when the value actual changes. I think this is a great solution because it avoids having to subclass or add new properties.
//Add action for `ValueChanged`
[toggleSwitch addTarget:self action:@selector(switchTwisted:) forControlEvents:UIControlEventValueChanged];
//Handle action
- (void)switchTwisted:(UISwitch *)twistedSwitch
{
if ([twistedSwitch isOn] && (![twistedSwitch isSelected]))
{
[twistedSwitch setSelected:YES];
//Write code for SwitchON Action
}
else if ((![twistedSwitch isOn]) && [twistedSwitch isSelected])
{
[twistedSwitch setSelected:NO];
//Write code for SwitchOFF Action
}
}
And here it is in Swift:
func doToggle(switch: UISwitch) {
if switch.on && !switch.selected {
switch.selected = true
// SWITCH ACTUALLY CHANGED -- DO SOMETHING HERE
} else {
switch.selected = false
}
}
Solution 4
Same bug here. I think I've found a simple workaround. We just have to use a new BOOL
that stores the previous state of the UISwitch
and an if statement in our IBAction
(Value Changed fired) to check that the value of the switch has actually changed.
previousValue = FALSE;
[...]
-(IBAction)mySwitchIBAction {
if(mySwitch.on == previousValue)
return;
// resetting the new switch value to the flag
previousValue = mySwitch.on;
}
No more weird behaviors. Hope it helps.
Solution 5
If you are using so many switch in your app then there is problem to change the code in all places where t action method of UISwitch is defined.You can make custom switch and handle the events only if value change.
CustomSwitch.h
#import <UIKit/UIKit.h>
@interface Care4TodayCustomSwitch : UISwitch
@end
CustomSwitch.m
@interface CustomSwitch(){
BOOL previousValue;
}
@end
@implementation CustomSwitch
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
previousValue = self.isOn;
}
return self;
}
-(void)awakeFromNib{
[super awakeFromNib];
previousValue = self.isOn;
self.exclusiveTouch = YES;
}
- (void)setOn:(BOOL)on animated:(BOOL)animated{
[super setOn:on animated:animated];
previousValue = on;
}
-(void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
if(previousValue != self.isOn){
for (id targetForEvent in [self allTargets]) {
for (id actionForEvent in [self actionsForTarget:targetForEvent forControlEvent:UIControlEventValueChanged]) {
[super sendAction:NSSelectorFromString(actionForEvent) to:targetForEvent forEvent:event];
}
}
previousValue = self.isOn;
}
}
@end
We are ignoring events if the value is same as changed value.Put CustomSwitch in all the class of UISwitch in storyboard.This will resolve the issue and call target only once when value changed
Nitin Gohel
#SOreadytohelp Upwork Top rated with 100% success rate Follow on Insta for batter reach : @nitin_gohel Currently i am working as a iOS Application Development Team Leader having over 10+ years of experience at OLBUZ PVT LTD. You can check my Career overview by following: Contact Me: Mail: [email protected] Skype: nitin.gohel10 PeoplePerHour twitter Linked In Profile My favorite app live on app store called ShareApp: Full: https://itunes.apple.com/in/app/shareapp-share-music-jokes/id949431104?mt=8 Lite: https://itunes.apple.com/in/app/shareapp-lite-share-music/id994866118?mt=8 67th person in the list of Highest reputation holder from India. Got 51th to the gold iOS badge Got 76th to the gold iPhone badge Proud to be INDIAN
Updated on March 05, 2020Comments
-
Nitin Gohel about 4 years
Edit
It's now fixed on ios7.1
Don't do any tweak to fix it.Edit2
Apparently the same problem happens again in iOS 8.0 and 8.1
Edit3
It's now fixed on ios9.2
Don't do any tweak to fix it.
Hi Today i seen in
UISwitch's
EventValueChanged:
Callingcontinuously
while i am change toOn
toOff
orOff
to On and my finger moved still on right side as well as left side. I atteched GIF image for more clear with NSLog.My Value Changed Method is:
- (IBAction)changeSwitch:(id)sender{ if([sender isOn]){ NSLog(@"Switch is ON"); } else{ NSLog(@"Switch is OFF"); } }
iOS6 the same code of Switch working Fine as we expectation:
so can anyone suggest me that call only one time its state On or off. or is this is a bug or what..?
UPDATE
Here it is my Demo of it:
-
Nitin Gohel over 10 yearsthx for answer as i said i was trying both way and got same result. atlist i knw how to add swtich programmatic as well as from xib sir.
-
Keegan Jay over 10 yearsthis should just say if(mySwitch.on == previousValue)
-
James C about 9 yearsThis worked for me. It's ideal in that it does not cause extraneous code to be manually added in your implementation files, as it's reusable and hides its implementation inside the class implementation. This is just good design. It would be nice if this answer had more comments though, because I don't really understand why all of the code is there.
-
Swayambhu over 8 yearsThanks, it worked for me. Can you explain the code a little bit more. @codester
-
Nick Kohrn over 8 yearsI, too, am still facing this issue in 9.2. I implemented your logic, and now it is working as I had intended.
-
zekel over 8 yearsI find this one to be simplest.
-
davidethell about 7 years+1'd this because it led me to using a similar solution of populating the .tag value when I want to ignore the toggle logic. I need the logic to fire sometimes in both on and off mode so the above wasn't quite sufficient.
-
Paul Semionov over 6 yearsWorked like a charm in iOS 11.2. In my situation, it fired 2 events in a row (state: off, swiping: off, 1st event: on, 2nd event: off), so a delay of 0.1s is enough for me and not noticeable to a user.