Detecting a change in UISwitch

后端 未结 8 1227
暖寄归人
暖寄归人 2021-02-18 14:19

This sounds trivial but I\'m noticing some weirdness. I\'ve wired up a handler for the Value Changed event of a UISwitch. What I would expect is that each time the hand

8条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-18 15:01

    Here's a solution that works for me. It also sends a property "will/did change" notification when the switch is changed. The event also functions correctly in that the before and after values are maintained correctly.

    @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
    

提交回复
热议问题