sourcetip

iOS7 UIswitch its Event Value Changed: 계속 전화하는 것이 이 버그인가요 아니면 뭐인가요?

fileupload 2023. 10. 10. 20:53
반응형

iOS7 UIswitch its Event Value Changed: 계속 전화하는 것이 이 버그인가요 아니면 뭐인가요?

편집

지금은 에서 수정되었습니다.
고치기 위해 손대지 마세요.

편집2

iOS 8.0과 8.1에서도 동일한 문제가 발생한다고 합니다.

편집3

지금은 에서 수정되었습니다.
고치기 위해 손대지 마세요.


오늘 요.UISwitch'stValueChanged: 중인gcontinuouslyo로 On.Off아니면Off온으로 가니까 손가락이 오른쪽, 왼쪽으로 계속 움직였어요.NSLog로 좀 더 선명하게 GIF 이미지를 첨부하였습니다.

enter image description here

My Value Changed Method:

- (IBAction)changeSwitch:(id)sender{

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

예상한 대로 스위치가 정상 작동하는 것과 동일한 iOS6 코드:

enter image description here

그래서 누가 한 번만 통화를 하라고 제안할 수 있습니까? 그것의 상태는 On or Off입니다.아니면 이게 벌레인가요?

갱신하다

여기 제 데모가 있습니다.

프로그래밍 추가 UI 스위치

XIB에서 UIS 스위치 추가

다음 코드를 참조하시기 바랍니다.

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

여기도 같은 벌레.간단한 해결책을 찾은 것 같습니다.우리는 단지 새로운 것을 사용하면 됩니다.BOOL합니다.UISwitch의에 .IBAction(Value Changed fired) 스위치의 값이 실제로 변경되었는지 확인합니다.

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

그리고 여기 스위프트에 있습니다.

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

당신의 앱에서 스위치를 그렇게 많이 사용하는 경우, UI 스위치의 taction method가 정의된 모든 곳에서 코드를 변경하는 문제가 발생합니다.값이 변경된 경우에만 사용자 지정 스위치를 만들고 이벤트를 처리할 수 있습니다.

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

값이 변경된 값과 동일한 경우 이벤트를 무시합니다.스토리보드의 모든 UIS 스위치 클래스에 Custom Switch를 넣습니다.이렇게 하면 문제가 해결되고 값이 변경될 때 한 번만 대상을 호출합니다.

는 많은 이 같은 해 있다고 은 의 도 있습니다.UISwitch그래서 나는 그것의 일시적인 해결책을 방금 찾았습니다.나는 하나 찾았어.gitHubmKLSwitch이 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믿음직스럽게 일을 처리합니다

iOS 9.2에서도 여전히 동일한 문제에 직면해 있습니다.

다른 사람들에게 도움이 될 것처럼 행동하고 해결책을 찾았습니다.

  1. 메서드가 호출을 받은 횟수를 추적할 카운트 변수 만들기

    int switchMethodCallCount = 0;
    
  2. 스위치 값에 대해 bool 값 저장

    bool isSwitchOn = No;
    
  3. 스위치의 값 변경 메서드는 첫 번째 메서드 호출에 대해서만 원하는 작업을 수행합니다.스위치 값이 다시 set count 값과 tool 변수 값을 default로 변경할 때

    - (IBAction)frontCameraCaptureSwitchToggle:(id)sender {
    
    
    
    //This method will be called multiple times if user drags on Switch,
    //But desire action should be perform only on first call of this method
    
    
    //1. 'switchMethodCallCount' variable is maintain to check number of calles to method,
    //2. Action is peform for 'switchMethodCallCount = 1' i.e first call
    //3. When switch value change to another state, 'switchMethodCallCount' is reset and desire action perform
    
    switchMethodCallCount++ ;
    
    //NSLog(@"Count --> %d", switchMethodCallCount);
    
    if (switchMethodCallCount == 1) {
    
    //NSLog(@"**************Perform Acction******************");
    
    isSwitchOn = frontCameraCaptureSwitch.on
    
    [self doStuff];
    
    }
    else
    {
    //NSLog(@"Do not perform");
    
    
    if (frontCameraCaptureSwitch.on != isSwitchOn) {
    
        switchMethodCallCount = 0;
    
        isSwitchOn = frontCameraCaptureSwitch.on
    
        //NSLog(@"Count again start");
    
        //call value change method again 
        [self frontCameraCaptureSwitchToggle:frontCameraCaptureSwitch];
    
    
        }
    }
    
    
    }
    

이 문제는 스위치를 다른 동작과 연결할 때 나를 괴롭힙니다.일반적으로 모든 것이 시작하는 것을 좋아하지 않습니다.on로.on. 간단한 해결책은 다음과 같습니다.

@interface MyView : UIView
@parameter (assign) BOOL lastSwitchState;
@parameter (strong) IBOutlet UISwitch *mySwitch;
@end

@implementation MyView

// Standard stuff goes here

- (void)mySetupMethodThatsCalledWhenever
{
    [self.mySwitch addTarget:self action:@selector(switchToggled:) forControlEvents:UIControlEventValueChanged];
}

- (void)switchToggled:(UISwitch *)someSwitch
{
    BOOL newSwitchState = self.mySwitch.on;
    if (newSwitchState == self.lastSwitchState)
    {
        return;
    }
    self.lastSwitchState = newSwitchState;

    // Do your thing
}

또한 설정해야 합니다.self.lastSwitchState수동으로 변경할 때마다mySwitch.on! :)

이러한 유형의 문제는 종종 ValueChanged로 인해 발생합니다.기능 실행을 위해 버튼을 누를 필요가 없습니다.터치 이벤트가 아닙니다.프로그래밍 방식으로 스위치를 On/Off로 변경할 때마다 값이 변경되고 IBaction 기능이 다시 호출됩니다.

@RoNiT의 정답은 다음과 같습니다.

스위프트

func doToggle(switch: UISwitch) {
    if switch.on && !switch.selected {
        switch.selected = true
        // SWITCH ACTUALLY CHANGED -- DO SOMETHING HERE
    } else {
        switch.selected = false
    }
}
DispatchQueue.main.async {
        self.mySwitch.setOn(false, animated: true)
    }

이것은 정상적으로 작동하고 셀렉터 기능을 다시 호출하지 않습니다.

저는 이게 통했어요.

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()){
    self.switch.isOn = true
}

언급URL : https://stackoverflow.com/questions/19628310/ios7-uiswitch-its-event-valuechanged-calling-continuously-is-this-bug-or-what

반응형