редактировать
Теперь это исправлено iOS7.1
Не делайте никаких настроек, чтобы исправить это.
Edit2
Видимо такая же проблема возникает снова в iOS 8.0 и 8.1.
Редактировать3
Теперь это исправлено iOS9.2
Не делайте никаких настроек, чтобы исправить это.
Привет Сегодня я видел в UISwitch's
Событии ValueChanged:
вызова в continuously
то время как я изменение в On
до Off
или Off
Вкл и мой палец перемещается еще на правой стороне, а также с левой стороны. Я сделал изображение GIF для большей ясности с помощью NSLog.
Мой метод изменения значения:
- (IBAction)changeSwitch:(id)sender{
if([sender isOn]){
NSLog(@"Switch is ON");
} else{
NSLog(@"Switch is OFF");
}
}
iOS6 тот же код Switch работает нормально, как мы и ожидали:
так что кто-нибудь может предложить мне, чтобы вызвать только один раз его состояние Вкл или Выкл. или это баг что ли ..?
ОБНОВИТЬ
Вот моя демонстрация:
Ответы:
См. Следующий код:
-(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
и оператор if в нашем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
's,.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 } }
источник
Если вы используете так много переключателей в своем приложении, тогда возникает проблема с изменением кода во всех местах, где определен метод действия t для UISwitch. Вы можете сделать пользовательский переключатель и обрабатывать события только при изменении значения.
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
Мы игнорируем события, если значение совпадает с измененным значением. Поместите CustomSwitch во все классы UISwitch в раскадровке. Это решит проблему и вызовет цель только один раз при изменении значения.
источник
У меня много пользователей, которые сталкиваются с одной и той же проблемой, так что, возможно, это ошибка,
UISwitch
поэтому я только что нашел ее временное решение. Я нашел одноgitHub
индивидуальноеKLSwitch
использование этого сейчас, надеюсь, что Apple исправит это в следующем обновлении 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
У меня есть решение и я представляю, как это может помочь другим
Создать переменную count для отслеживания количества вызовов метода
int switchMethodCallCount = 0;
Сохранить значение bool для значения переключателя
bool isSwitchOn = No;
В методе изменения значения Switch выполняйте действие желания только для первого вызова метода. Когда значение переключателя снова изменяет установленное значение счетчика и значение переменной bool на значение по умолчанию
- (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. Вам не нужно нажимать кнопку для запуска функции. Это не прикосновение. Каждый раз, когда вы программно переключаете переключатель в положение включения / выключения, значение изменяется, и функция IBAction снова вызывается.
@RoNiT дал правильный ответ:
Swift
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 }
источник