ios 检测 UISwitch 的变化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4098653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting a change in UISwitch
提问by John
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 expectis that each time the handler is called the value of the switch would change. But that's actually not alwaysthe case. If you press the switch rapidly on/off the handler can get called consecutively with the SAME state for the switch (in my specific application this is an issue). So I'm wondering if anyone else has noticed this behavior and has figured out a good solution.
这听起来微不足道,但我注意到一些奇怪的地方。我已经为 UISwitch 的 Value Changed 事件连接了一个处理程序。我期望的是,每次调用处理程序时,开关的值都会改变。但实际上并非总是如此。如果您快速打开/关闭开关,则可以使用开关的 SAME 状态连续调用处理程序(在我的特定应用程序中,这是一个问题)。所以我想知道是否有其他人注意到这种行为并找到了一个好的解决方案。
回答by user1105951
-(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;
}
回答by Erdemus
Get state of switch in handler:
获取处理程序中的开关状态:
- (void)valueChanged:(UISwitch *)theSwitch {
BOOL flag = theSwitch.on;
}
回答by antsyawn
Each press you make doesn't immediately toggle the switch on/off. If the switch is in the off position, you can get a couple of presses in before it animates to the on position. Each of these presses are interpreted as "turn the switch on", since it is not considered "on" until the animation has completed. You get a "valueChanged" callback for each press despite the fact that the value hasn't actually changed yet.
您每次按下都不会立即打开/关闭开关。如果开关处于关闭位置,您可以在它动画到打开位置之前按下几次。每一次按下都被解释为“打开开关”,因为在动画完成之前它不会被视为“打开”。尽管值实际上尚未更改,但每次按下都会收到“valueChanged”回调。
回答by Vadim Bulavin
In iOS 11 a new UISwitch bugwas introduced so I don't recommend subscribing to value changed events. Otherwise your callback will be triggered every time UISwitch
's isOn
attribute changes programmatically.
在 iOS 11中引入了一个新的 UISwitch 错误,因此我不建议订阅值更改事件。否则,每次以编程方式更改UISwitch
的isOn
属性时都会触发您的回调。
Instead:
反而:
1) Subscribe for touch up inside event:
1) 订阅修饰内部事件:
let switch = UISwitch()
switch.addTarget(self, action: #selector(onSwitchValueChanged), for: .touchUpInside)
2) Implement the callback method:
2)实现回调方法:
func onSwitchValueChanged(_ switch: UISwitch) {
}
3) And now when you programmatically change isOn
value, it won't trigger onSwitchValueChanged
method.
3)现在当您以编程方式更改isOn
值时,它不会触发onSwitchValueChanged
方法。
switch.isOn = !switch.isOn // 'onSwitchValueChanged' is not triggered
switch.isOn = !switch.isOn // 'onSwitchValueChanged' is not triggered
回答by Leslie Godwin
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
回答by Mike
My problem was a stupid one... I was expecting the enabled
value to change, but obviously that isn't the correct value to inspect upon the toggle of the switch, the on
or isOn
is the correct thing to use.
我的问题是一个愚蠢的问题......我期待enabled
值会改变,但显然这不是检查开关切换的正确值,on
orisOn
是正确的使用方法。
回答by nids
When you toggle the switch off/On the "value changed" has been called.So you can detecting a change in switch by calling method on valueChanged.
当您关闭/打开开关时,“值已更改”已被调用。因此,您可以通过调用 valueChanged 方法来检测开关的更改。
回答by Ben
Log the last state so you can tell if its changed state or has been triggered with the same state.
记录最后一个状态,以便您可以判断其状态是否已更改或已被相同状态触发。