Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS7 UISwitch its Event ValueChanged: Calling continuously is this Bug or what..?

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 Event ValueChanged: Calling continuously while i am change to On to Off or Off to On and my finger moved still on right side as well as left side. I atteched GIF image for more clear with NSLog.

enter image description here

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:

enter image description here

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:

programmatic Add UISwitch

from XIB adding UISwitch

like image 979
Nitin Gohel Avatar asked Oct 28 '13 06:10

Nitin Gohel


3 Answers

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");
    }
}
like image 86
AeroStar Avatar answered Nov 18 '22 05:11

AeroStar


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.

like image 12
nnarayann Avatar answered Nov 18 '22 07:11

nnarayann


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
    }
}
like image 12
itsji10dra Avatar answered Nov 18 '22 07:11

itsji10dra