2010-11-04 66 views
19

这听起来很平凡,但我注意到一些奇怪。我已经为UISwitch的Value Changed事件连接了一个处理程序。我会期望是,每次处理程序被称为开关的值会改变。但实际上并非总是的情况。如果你按下开关快速开/关,处理程序可以连续调用交换机的SAME状态(在我的具体应用中,这是一个问题)。所以我想知道是否有其他人注意到这种行为,并找到了一个很好的解决方案。检测到UISwitch的变化

回答

0

记录最后一个状态,以便可以确定其状态是否已更改或是否已使用相同状态触发。

8

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

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

每按一次,你做不立即切换上/开关关闭。如果开关处于关闭位置,您可以在启动到开启位置之前进行几次按压。这些印刷机中的每一个被解释为“打开开关”,因为在动画完成之前它不被视为“开”。尽管事实上这个数值还没有真正改变,你仍然可以为每个媒体获得一个“valueChanged”回调。

0

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

15
-(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; 
    } 
+0

不是一个学究,但对于其'on'属性'UISwitch' getter函数是'isOn',所以这行应为'BOOL标志= theSwitch.isOn'。 – 2016-12-01 22:06:45

+0

测试并编译。 – user1105951 2016-12-02 14:20:02

+0

我没有说它不会工作(我知道它会);我说过你没有使用这个属性的getter函数。 – 2016-12-02 17:35:49

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 
0

我的问题是一个愚蠢的一个......我期待enabled值改变,但显然不是在开关的切换,以检查正确的值时,onisOn是正确的要使用的东西。

1

在iOS 11中引入了new UISwitch bug,所以我不建议订阅改变值的事件。否则,每次UISwitchisOn属性以编程方式更改时,都会触发您的回调。

相反:

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