93

編集

現在は
で修正されています。修正するための微調整は行わないでください。

編集2

どうやら iOS 8.0 と 8.1 で同じ問題が再び発生するようです

編集3

現在は
で修正されています。修正するための微調整は行わないでください。


こんにちは、今日、UISwitch'sイベントValueChanged:コーリングでオンまたはオンcontinuously に変更しているOnのを見ましたが、指は左側だけでなく右側にも移動しました。NSLogでより明確にするためにGIF画像を添付しました。OffOff

ここに画像の説明を入力

私の値の変更方法は次のとおりです。

- (IBAction)changeSwitch:(id)sender{

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

iOS6 スイッチの同じコードは、期待どおりに正常に動作します。

ここに画像の説明を入力

そのため、状態のオンまたはオフを1回だけ呼び出すことを誰でも提案できます。それともこれはバグですか、それとも何ですか..?

アップデート

これが私のデモです:

プログラムによる UISwitch の追加

UISwitch を追加する XIB から

4

12 に答える 12

45

次のコードを参照してください。

-(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");
    }
}
于 2013-10-28T07:38:52.347 に答える
12

UISwitchのプロパティを使用して、.selected実際の値が変更されたときにコードが 1 回だけ実行されるようにすることができます。サブクラス化や新しいプロパティの追加が不要になるため、これは優れたソリューションだと思います。

 //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
    }
}
于 2015-11-06T08:21:15.263 に答える
9

アプリで非常に多くのスイッチを使用している場合、UISwitch の t アクション メソッドが定義されているすべての場所でコードを変更するという問題があります。カスタム スイッチを作成し、値が変更された場合にのみイベントを処理できます。

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 を配置します。これにより、問題が解決され、値が変更されたときにターゲットが 1 回だけ呼び出されます。

于 2014-03-23T22:05:54.187 に答える
7

同じ問題に直面している多くのユーザーがいるので、これはバグである可能性があるUISwitchため、一時的な解決策として今見つけました。アップルが次のxCodeのアップデートでこれを修正することを願っています: gitHub-KLSwitch

https://github.com/KieranLafferty/KLSwitch

于 2013-10-28T06:47:40.950 に答える
6

スイッチの値の変更に即座に反応する必要がない場合は、次の方法が解決策になる可能性があります。

- (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];
  }
}
于 2013-11-20T17:21:49.787 に答える
3

この問題は、iOS 9.3 ベータ版の時点でも存在します。ユーザーがスイッチの外にドラッグできないことを気にしない場合は、確実に機能するの.TouchUpInsideではなく、使用することがわかります。.ValueChanged

于 2016-02-19T18:54:47.817 に答える
2

iOS 9.2 でも同じ問題に直面しています。

私は解決策を得て、他の人を助けるかもしれないとポーズをとった

  1. メソッドが呼び出された回数を追跡するカウント変数を作成する

    int switchMethodCallCount = 0;
    
  2. スイッチ値のブール値を保存

    bool isSwitchOn = No;
    
  3. Switch の値変更メソッドでは、最初のメソッド呼び出しに対してのみ、desire アクションを実行します。スイッチ値が再び変更されたら、カウント値とブール変数値をデフォルトに設定します

    - (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];
    
    
        }
    }
    
    
    }
    
于 2016-01-19T13:55:15.543 に答える
2

スイッチを他の動作に結び付けると、この問題に悩まされます。通常、物事は から に移動するのが好きではありませonon。これが私の簡単な解決策です:

@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。:)

于 2016-04-21T21:55:39.840 に答える