Подтвердить что ты не робот

Обнаружение изменений в UISwitch

Это звучит тривиально, но я замечаю какую-то странность. Я подключил обработчик события Value Changed для UISwitch. Я бы ожидал, что каждый раз, когда обработчик называется значением переключателя, он изменится. Но на самом деле это не всегда так. Если вы быстро нажимаете на переключатель, обработчик может получить вызов последовательно с состоянием SAME для коммутатора (в моем конкретном приложении это проблема). Поэтому мне интересно, заметил ли кто-нибудь еще это поведение и нашел хорошее решение.

4b9b3361

Ответ 1

   -(void) createSwitch
    {
        self.searchExistSearchNewSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0,0,0,0)];
        [self.searchExistSearchNewSwitch addTarget:self action:@selector(switchValueChanged:) forControlEvents:UIControlEventValueChanged];
        [self.view addSubview:self.searchExistSearchNewSwitch];
    }
    - (void)switchValueChanged:(UISwitch *)theSwitch
    {
        BOOL flag = theSwitch.isOn;
    }

Ответ 2

Получить состояние переключателя в обработчике:

- (void)valueChanged:(UISwitch *)theSwitch {
   BOOL flag = theSwitch.on;
}

Ответ 3

Каждое нажатие, которое вы делаете, не переключает переключатель вкл./выкл. Если переключатель находится в выключенном положении, вы можете получить пару нажатий, прежде чем он оживет в положение включения. Каждое из этих прессов интерпретируется как "включить переключатель", так как он не считается "on", пока анимация не завершится. Вы получаете обратный вызов "valueChanged" для каждого нажатия, несмотря на то, что значение еще не изменилось.

Ответ 4

Вот решение, которое работает для меня. Он также отправляет уведомление об изменении "будет/изменено" при изменении переключателя. Событие также функционирует правильно, так как значения до и после сохраняются правильно.

@interface MySwitch : UISwitch

@end

@implementation MySwitch
{
    BOOL _previousValue;
    BOOL _returnPreviousValue;
}

- (instancetype) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder: aDecoder];
    if (!self) return nil;

    _previousValue = self.isOn;
    [self addTarget: self action: @selector(_didChange)
                forControlEvents: UIControlEventValueChanged];

    return self;
}

- (instancetype) initWithFrame: (CGRect) frame
{
    self = [super initWithFrame: frame];
    if (!self) return nil;

    [self addTarget: self action: @selector(_didChange)
                forControlEvents: UIControlEventValueChanged];

    return self;
}

- (BOOL) isOn
{
    return (_returnPreviousValue)
                        ? _previousValue
                        : [super isOn];
}

- (void) setOn:(BOOL) on animated: (BOOL) animated
{
    [super setOn: on animated: animated];

    _previousValue = on;
}

- (void) _didChange
{
    BOOL isOn = self.isOn;

    if (isOn == _previousValue) return;

    _returnPreviousValue = true;
    [self willChangeValueForKey: @"on"];
    _returnPreviousValue = false;

    _previousValue = isOn;
    [self didChangeValueForKey:  @"on"];
}

@end

Ответ 5

В iOS 11 была введена новая ошибка UISwitch, поэтому я не рекомендую подписываться на значения измененных событий. В противном случае ваш обратный вызов будет запускаться каждый раз, когда атрибут UISwitch isOn программно изменяется.

Вместо этого:

1) Подпишитесь на контакт внутри события:

let switch = UISwitch()
switch.addTarget(self, action: #selector(onSwitchValueChanged), for: .touchUpInside)

2) Внедрить метод обратного вызова:

func onSwitchValueChanged(_ switch: UISwitch) {

}

3) И теперь, когда вы программно меняете значение isOn, оно не будет запускать метод onSwitchValueChanged.

switch.isOn = !switch.isOn // 'onSwitchValueChanged' is not triggered

Ответ 6

Запишите последнее состояние, чтобы вы могли узнать, было ли изменено его состояние или было вызвано с тем же состоянием.

Ответ 7

При переключении выключения/включения вызывается "значение изменено". Таким образом, вы можете обнаружить изменение в переключателе, вызвав метод на valueChanged.

Ответ 8

Моя проблема была глупой... Я ожидал, что значение enabled изменится, но, очевидно, это неверное значение для проверки переключателя коммутатора, on или isOn правильная вещь для использования.