检测UISwitch中的更改

时间:2010-11-04 16:06:47

标签: ios cocoa-touch uiswitch

这听起来微不足道,但我注意到一些奇怪。我为UISwitch的Value Changed事件连接了一个处理程序。我希望期望是每次调用处理程序时,交换机的值都会改变。但实际上并非始终的情况。如果您快速打开/关闭开关,则可以使用交换机的SAME状态连续调用处理程序(在我的特定应用程序中,这是一个问题)。所以我想知道是否有其他人注意到这种行为,并找到了一个很好的解决方案。

8 个答案:

答案 0 :(得分:17)

   -(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;
    }

答案 1 :(得分:8)

获取处理程序中的开关状态:

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

答案 2 :(得分:7)

每按一次,都不会立即打开/关闭开关。如果开关处于关闭位置,您可以在其动画到开启位置之前进行几次按压。这些按下中的每一个都被解释为“打开开关”,因为在动画完成之前它不被视为“开启”。尽管该值尚未真正改变,但每次按下都会得到一个“valueChanged”回调。

答案 3 :(得分:4)

在iOS 11中引入了new UISwitch bug,因此我不建议订阅价值更改事件。否则,每次 [1]: https://jsfiddle.net/oxxLnk7s/1/ UISwitch属性以编程方式更改时,系统都会触发您的回调。

相反:

1)订阅内部活动:

isOn

2)实现回调方法:

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

3)现在,当您以编程方式更改func onSwitchValueChanged(_ switch: UISwitch) { } 值时,它不会触发isOn方法。

onSwitchValueChanged

答案 4 :(得分:1)

这是一个适合我的解决方案。 当交换机发生变化时,它还会发送一个属性“will / did change”通知。 事件也正常运行,前后值正确维护。

@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 :(得分:0)

记录最后一个状态,以便判断其状态是否已更改或是否已以相同状态触发。

答案 6 :(得分:0)

当您关闭/关闭开关时,已调用“已更改值”。因此,您可以通过调用valueChanged上的方法来检测开关中的更改。

答案 7 :(得分:0)

我的问题是一个愚蠢的问题...我期待enabled值改变,但显然这不是检查交换机切换的正确值,onisOn是正确的用法。