检测UISwitch中的更改

这听起来微不足道,但我注意到一些怪异。 我已经为UISwitch的Value Changed事件连接了一个处理程序。 我所期望的是,每次处理程序被调用时,交换机的值都会改变。 但事实并非如此。 如果你按下开关快速开/关处理程序可以连续调用与交换机的相同状态(在我的具体应用这是一个问题)。 所以我想知道是否有其他人注意到这种行为,并find了一个很好的解决scheme。

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

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

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

您所做的每次按都不会立即打开/closures开关。 如果开关处于closures位置,可以在启动到开启位置之前进行几次按压。 这些印刷机中的每一个被解释为“打开开关”,因为在animation完成之前它不被认为是“开”。 尽pipe事实上这个值还没有真正改变,但是每个媒体都会得到一个“valueChanged”callback。

这是一个适合我的解决scheme。 当交换机改变时,它也发送一个属性“将/更改”通知。 该事件也正确运行,因为前后值保持正确。

 @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 

在iOS 11中引入了一个新的UISwitch错误 ,所以我不推荐订阅改变值的事件。 否则,每次UISwitchisOn属性以编程方式更改时,都会触发callback。

代替:

1)订阅内幕事件:

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

2)实现callback方法:

 func onSwitchValueChanged(_ switch: UISwitch) { } 

3)现在当你编程改变isOn值时,它不会触发onSwitchValueChanged方法。

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

logging最后一个状态,以便可以判断其状态是否改变或是否已经被触发。

当closures/打开开关时,已经调用了“数值改变”。所以你可以通过调用valueChanged方法来检测开关的改变。

我的问题是一个愚蠢的…我期待enabled值改变,但显然,这是不正确的值来检查开关的切换, onisOn是正确的使用。