现已修复ios7.1
不要做任何调整来解决它。
显然,在iOS 8.0和8.1中再次出现同样的问题
现已修复ios9.2
不要做任何调整来解决它。
嗨今天我在UISwitch's
活动ValueChanged:
中看到,当我更改为continuously
至On
或Off
至开启时,请致电Off
我的手指仍然在右侧和左侧移动。我使用NSLog更加清晰地看了GIF图像。
我的价值改变方法是:
- (IBAction)changeSwitch:(id)sender{
if([sender isOn]){
NSLog(@"Switch is ON");
} else{
NSLog(@"Switch is OFF");
}
}
iOS6相同的Switch代码工作正常,我们期待:
所以任何人都可以建议我只打电话或关闭一次状态。或者这是一个错误或什么..?
更新
这是我的演示:
答案 0 :(得分:44)
请参阅以下代码:
-(void)viewDidLoad
{
[super viewDidLoad];
UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(130, 235, 0, 0)];
[mySwitch addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:mySwitch];
}
- (void)changeSwitch:(id)sender{
if([sender isOn]){
NSLog(@"Switch is ON");
} else{
NSLog(@"Switch is OFF");
}
}
答案 1 :(得分:12)
这里有同样的错误。我想我找到了一个简单的解决方法。我们只需要使用一个新的BOOL
来存储UISwitch
的先前状态和IBAction
中的if语句(触发值已更改)以检查交换机的值是否实际改变。
previousValue = FALSE;
[...]
-(IBAction)mySwitchIBAction {
if(mySwitch.on == previousValue)
return;
// resetting the new switch value to the flag
previousValue = mySwitch.on;
}
没有更奇怪的行为。希望它有所帮助。
答案 2 :(得分:12)
您可以使用UISwitch
的{{1}}属性来确保您的代码仅在值实际更改时执行一次。我认为这是一个很好的解决方案,因为它避免了必须子类化或添加新属性。
.selected
这里是Swift:
//Add action for `ValueChanged`
[toggleSwitch addTarget:self action:@selector(switchTwisted:) forControlEvents:UIControlEventValueChanged];
//Handle action
- (void)switchTwisted:(UISwitch *)twistedSwitch
{
if ([twistedSwitch isOn] && (![twistedSwitch isSelected]))
{
[twistedSwitch setSelected:YES];
//Write code for SwitchON Action
}
else if ((![twistedSwitch isOn]) && [twistedSwitch isSelected])
{
[twistedSwitch setSelected:NO];
//Write code for SwitchOFF Action
}
}
答案 3 :(得分:9)
如果您在应用中使用了这么多开关,那么在所有地方更改代码都会出现问题 定义了UISwitch的动作方法。只有在值发生变化时,才能进行自定义切换和处理事件。
CustomSwitch.h
#import <UIKit/UIKit.h>
@interface Care4TodayCustomSwitch : UISwitch
@end
CustomSwitch.m
@interface CustomSwitch(){
BOOL previousValue;
}
@end
@implementation CustomSwitch
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
previousValue = self.isOn;
}
return self;
}
-(void)awakeFromNib{
[super awakeFromNib];
previousValue = self.isOn;
self.exclusiveTouch = YES;
}
- (void)setOn:(BOOL)on animated:(BOOL)animated{
[super setOn:on animated:animated];
previousValue = on;
}
-(void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{
if(previousValue != self.isOn){
for (id targetForEvent in [self allTargets]) {
for (id actionForEvent in [self actionsForTarget:targetForEvent forControlEvent:UIControlEventValueChanged]) {
[super sendAction:NSSelectorFromString(actionForEvent) to:targetForEvent forEvent:event];
}
}
previousValue = self.isOn;
}
}
@end
如果值与更改的值相同,我们将忽略事件。在故事板中的所有类UISwitch中输入CustomSwitch。这将解决问题并在值更改时仅调用目标
答案 4 :(得分:7)
我遇到了许多面临同样问题的用户,所以可能是UISwitch
的错误,所以我现在才发现它的临时解决方案。我发现一个gitHub
自定义KLSwitch
现在使用此希望苹果将在xCode的下一次更新中修复此问题: -
答案 5 :(得分:6)
如果您不需要立即对交换机的值进行更改,则以下内容可能是一个解决方案:
- (IBAction)switchChanged:(id)sender {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
if ([switch isOn]) {
[self performSelector:@selector(enable) withObject:nil afterDelay:2];
} else {
[self performSelector:@selector(disable) withObject:nil afterDelay:2];
}
}
答案 6 :(得分:3)
从iOS 9.3测试版开始,此问题仍然存在。如果您不介意用户无法在交换机外拖动,我发现使用.TouchUpInside
而不是.ValueChanged
可以正常工作。
答案 7 :(得分:2)
我在iOS 9.2中仍面临同样的问题
我得到了解决方案并且冒充,因为它可能会帮助其他人
创建计数变量以跟踪方法调用的次数
int switchMethodCallCount = 0;
保存切换值的bool值
bool isSwitchOn = No;
在Switch的值更改方法中,仅对第一个方法调用执行欲望操作。当切换值再次将设置计数值和t bool变量值更改为默认值
时- (IBAction)frontCameraCaptureSwitchToggle:(id)sender {
//This method will be called multiple times if user drags on Switch,
//But desire action should be perform only on first call of this method
//1. 'switchMethodCallCount' variable is maintain to check number of calles to method,
//2. Action is peform for 'switchMethodCallCount = 1' i.e first call
//3. When switch value change to another state, 'switchMethodCallCount' is reset and desire action perform
switchMethodCallCount++ ;
//NSLog(@"Count --> %d", switchMethodCallCount);
if (switchMethodCallCount == 1) {
//NSLog(@"**************Perform Acction******************");
isSwitchOn = frontCameraCaptureSwitch.on
[self doStuff];
}
else
{
//NSLog(@"Do not perform");
if (frontCameraCaptureSwitch.on != isSwitchOn) {
switchMethodCallCount = 0;
isSwitchOn = frontCameraCaptureSwitch.on
//NSLog(@"Count again start");
//call value change method again
[self frontCameraCaptureSwitchToggle:frontCameraCaptureSwitch];
}
}
}
答案 8 :(得分:2)
This problem plagues me when I tie the switch to other behaviors. Generally things don't like to go from on
to on
. Here's my simple solution:
@interface MyView : UIView
@parameter (assign) BOOL lastSwitchState;
@parameter (strong) IBOutlet UISwitch *mySwitch;
@end
@implementation MyView
// Standard stuff goes here
- (void)mySetupMethodThatsCalledWhenever
{
[self.mySwitch addTarget:self action:@selector(switchToggled:) forControlEvents:UIControlEventValueChanged];
}
- (void)switchToggled:(UISwitch *)someSwitch
{
BOOL newSwitchState = self.mySwitch.on;
if (newSwitchState == self.lastSwitchState)
{
return;
}
self.lastSwitchState = newSwitchState;
// Do your thing
}
Just be sure to also set self.lastSwitchState
every time you manually change mySwitch.on
! :)
答案 9 :(得分:1)
此类问题通常由ValueChanged引起。您无需按此按钮即可运行该功能。这不是触摸事件。每次以编程方式将开关更改为开/关时,值都会更改,并再次调用IBAction函数。
@RoNiT得到了正确答案:
斯威夫特
func doToggle(switch: UISwitch) {
if switch.on && !switch.selected {
switch.selected = true
// SWITCH ACTUALLY CHANGED -- DO SOMETHING HERE
} else {
switch.selected = false
}
}
答案 10 :(得分:0)
DispatchQueue.main.async {
self.mySwitch.setOn(false, animated: true)
}
这样可以正常工作,并且不会再次调用选择器功能。
答案 11 :(得分:0)
这对我有用。
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()){
self.switch.isOn = true
}