[ios] iOS7 UISwitch 이벤트 ValueChanged : 지속적으로 호출하는 것은이 버그 또는 무엇입니까 ..?

편집하다

이제 수정되었습니다.

그것을 고치기 위해 어떤 조정도하지 마십시오.

편집 2

분명히 동일한 문제가 iOS 8.0 및 8.1에서 다시 발생합니다.

편집 3

이제 수정되었습니다.

그것을 고치기 위해 어떤 조정도하지 마십시오.


안녕하세요 오늘은 내가 볼 UISwitch's이벤트 ValueChanged:를 호출 continuously 난에 변화를 생각하면서 On까지 Off또는 OffOn으로 내 손가락을 왼쪽뿐만 아니라 오른쪽에 여전히 움직였다. NSLog로 더 명확하게 GIF 이미지를 만들었습니다.

여기에 이미지 설명 입력

내 가치 변경 방법은 다음과 같습니다.

- (IBAction)changeSwitch:(id)sender{

    if([sender isOn]){
        NSLog(@"Switch is ON");
    } else{
        NSLog(@"Switch is OFF");
    }
    
}

iOS6 스위치의 동일한 코드가 예상대로 잘 작동합니다.

여기에 이미지 설명 입력

그래서 누구든지 그 상태를 On 또는 Off로 한 번만 호출하도록 제안 할 수 있습니다. 아니면이게 벌레 야 ..?

최신 정보

여기 내 데모가 있습니다.

프로그래밍 방식 추가 UISwitch

XIB에서 UISwitch 추가



답변

다음 코드를 참조하십시오.

-(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");
    }
}


답변

여기에도 같은 버그가 있습니다. 간단한 해결 방법을 찾은 것 같습니다. 스위치의 값이 실제로 변경되었는지 확인하기 위해 (Value Changed fired)에 if 문과 BOOL의 이전 상태를 저장 하는 new를 사용해야합니다 .UISwitchIBAction

previousValue = FALSE;

[...]

-(IBAction)mySwitchIBAction {
    if(mySwitch.on == previousValue)
        return;
    // resetting the new switch value to the flag
    previousValue = mySwitch.on;
 }

더 이상 이상한 행동이 없습니다. 도움이되기를 바랍니다.


답변

UISwitch.selected속성을 사용하여 실제 값이 변경 될 때 코드가 한 번만 실행되도록 할 수 있습니다 . 하위 클래스를 만들거나 새 속성을 추가 할 필요가 없기 때문에 이것이 훌륭한 솔루션이라고 생각합니다.

 //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
    }
}

그리고 여기 Swift에 있습니다.

func doToggle(switch: UISwitch) {
    if switch.on && !switch.selected {
        switch.selected = true
        // SWITCH ACTUALLY CHANGED -- DO SOMETHING HERE
    } else {
        switch.selected = false
    }
}


답변

앱에서 너무 많은 스위치를 사용하는 경우 UISwitch의 t action 메소드가 정의 된 모든 곳에서 코드를 변경해야하는 문제가 있습니다. 사용자 정의 스위치를 만들고 값이 변경된 경우에만 이벤트를 처리 할 수 ​​있습니다.

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

값이 변경된 값과 동일한 경우 이벤트를 무시하고 스토리 보드의 모든 UISwitch 클래스에 CustomSwitch를 넣으면 문제가 해결되고 값이 변경된 경우 대상을 한 번만 호출합니다.


답변

나는 같은 문제에 직면 한 많은 사용자가 있으므로 이것이 버그 일 수 UISwitch있으므로 일시적인 해결책을 찾았습니다. 나는 지금 이것을 사용하는 하나의 gitHub사용자 정의를 찾았습니다 KLSwitch. xCode의 다음 업데이트에서 사과가 이것을 고칠 것입니다.

https://github.com/KieranLafferty/KLSwitch


답변

스위치의 값 변경에 즉시 반응 할 필요가 없다면 다음이 해결책이 될 수 있습니다.

- (IBAction)switchChanged:(id)sender {
  [NSObject cancelPreviousPerformRequestsWithTarget:self];

  if ([switch isOn]) {
      [self performSelector:@selector(enable) withObject:nil afterDelay:2];
  } else {
      [self performSelector:@selector(disable) withObject:nil afterDelay:2];
  }
}


답변

이 문제는 iOS 9.3 베타에서 여전히 여기에 있습니다. 사용자가 스위치 외부로 드래그 할 수 없다는 점에 신경 쓰지 않는다면 안정적으로 작동 하는 .TouchUpInside대신 사용 하는 것을 알 .ValueChanged수 있습니다.