IOS7 UISwitch его событие ValueChanged: постоянно звонит это ошибка или что..?
Изменить
Теперь он исправлен на ios7.1
Не пытайтесь исправить это.
Edit2
По-видимому, такая же проблема повторится и в iOS 8.0 и 8.1
Edit3
Теперь он исправлен на ios9.2
Не пытайтесь исправить это.
Привет Сегодня я видел в UISwitch's
Событие ValueChanged:
Вызов continuously
, пока я меняю на On
на Off
или Off
на "Вкл", и мой палец перемещается по-прежнему с правой стороны, а также с левой стороны, Я закрепил GIF-изображение для более четкого представления в NSLog.
![enter image description here]()
Мой измененный метод:
- (IBAction)changeSwitch:(id)sender{
if([sender isOn]){
NSLog(@"Switch is ON");
} else{
NSLog(@"Switch is OFF");
}
}
iOS6 тот же самый код коммутатора работает как ожидалось:
![enter image description here]()
так может ли кто-нибудь предложить мне, чтобы он вызывал только одно время его состояние вкл. или выкл. или это ошибка или что..?
UPDATE
Вот моя демонстрация:
программный Добавить UISwitch
из XIB, добавляющего UISwitch
Ответы
Ответ 1
У меня появилось много пользователей, которые сталкиваются с одной проблемой, поэтому может быть, это ошибка UISwitch
, поэтому я нашел ее только для временного решения. Я нашел один gitHub
пользовательский KLSwitch
использовать это, теперь надеюсь, что apple исправит это в следующем обновлении xCode: -
https://github.com/KieranLafferty/KLSwitch
Ответ 2
См. следующий код:
-(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");
}
}
Ответ 3
Такая же ошибка здесь. Я думаю, что нашел простой способ обхода. Нам просто нужно использовать новый BOOL
, который сохраняет предыдущее состояние UISwitch
и оператор if в нашем IBAction
(Value Changed), чтобы проверить, действительно ли значение переключателя было изменено.
previousValue = FALSE;
[...]
-(IBAction)mySwitchIBAction {
if(mySwitch.on == previousValue)
return;
// resetting the new switch value to the flag
previousValue = mySwitch.on;
}
Нет более странного поведения. Надеюсь, что это поможет.
Ответ 4
Вы можете использовать свойство 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
}
}
Ответ 5
Если вы используете так много переключателей в своем приложении, тогда возникает проблема с изменением кода во всех местах, где 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 в раскадровке. Это решит проблему и вызовет цель только один раз, когда значение изменится
Ответ 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];
}
}
Ответ 7
Я все еще сталкиваюсь с той же проблемой в iOS 9.2
Я получил решение и позировал, поскольку это могло бы помочь другим
-
Создать счетную переменную для отслеживания количества раз, когда метод получил вызов
int switchMethodCallCount = 0;
-
Сохранить значение bool для значения переключателя
bool isSwitchOn = No;
-
В методе изменения значения переключателя выполняется действие желания только для первого вызова метода. Когда значение переключателя снова изменяет значение счетчика установки и значение переменной 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];
}
}
}
Ответ 8
Эта проблема все еще здесь, как и бета-версия iOS 9.3. Если вы не возражаете против того, что пользователь не может перетащить за пределы коммутатора, я считаю, что использование .TouchUpInside
, а не .ValueChanged
работает надежно.
Ответ 9
Эта проблема поражает меня, когда я привязываю переключатель к другому поведению. Обычно вещи не любят идти от 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
!:)
Ответ 10
Этот тип проблемы часто вызван 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
}
}