1.UISwitch的问题
UISwitch
通常这样使用:
UISwitch *showPhoneNumSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(80.f, 10.f, 100.f, 40.f)];
[showPhoneNumSwitch setOn:YES];
[showPhoneNumSwitch addTarget:self action:@selector(handleShowPhoneNumSwitch:) forControlEvents:UIControlEventValueChanged];
监听UIControlEventValueChanged
事件,当UISwitch
的值改变时就会调用handleShowPhoneNumSwitch
:方法,如下:
- (void) handleShowPhoneNumSwitch:(id)sender
{
UISwitch *switchButton = (UISwitch*)sender;
BOOL isOn = [switchButton isOn];
NSLog(@"当前值是:%@", isOn ? @"YES" : @"NO");
}
问题来了,如果手指在UISwitch
控件上滑动,划出控件区域之后,手指不抬起,手指继续在屏幕上滑动,可以看到控制台一直在重复打印当前的状态,
如果我们直接在这个方法里面处理一些事务,比如提交网络请求,那么这些事务将重复执行完全一致的逻辑,消耗无谓的资源,甚至可能出现逻辑错误,比如下面这种逻辑:
- (void) handleShowPhoneNumSwitch:(id)sender
{
UISwitch *switchButton = (UISwitch*)sender;
BOOL isOn = [switchButton isOn];
NSLog(@"当前值是:%@", isOn ? @"YES" : @"NO");
_isShowPhoneNum = isOn;
[[ServiceFactory service] requestModifyPhoneNumPrivacyConfig
:self.teamUin showPhoneNum: _isShowPhoneNum handler:^(uint32_t errorCode, id resp) {
if (errorCode != 0) {
[switchButton setOn:!_isShowPhoneNum animated:YES]; // 网络请求返回错误,这里给 UISwitch 设置了相反的值
}
}];
}
如上这种逻辑,在网络请求错误的时候,会把UISwitch
的值设置为相反的值,如果这时候手指继续滑动,那么又会触发UIControlEventValueChanged
进来这个方法,网络错误的地方又会设置相反的值,这样两种值交替出现。最终的效果可能是并非我们想要的效果。
2.解决方案:
其实在手指滑动的时候,UISwitch
的值并未发生改变,只是重复触发UIControlEventValueChanged
,可以在方法内先进行一个判断,如果当前值跟上一次的值一样,那么就不需要执行方法里面的逻辑。
代码修正如下:
- (void) handleShowPhoneNumSwitch:(id)sender
{
UISwitch *switchButton = (UISwitch*)sender;
BOOL isOn = [switchButton isOn];
if (isOn != _isShowPhoneNum) { // 判断是否与上次进来相同
_isShowPhoneNum = isOn;
[[ServiceFactory service] requestModifyPhoneNumPrivacyConfig
:self.teamUin showPhoneNum: _isShowPhoneNum handler:^(uint32_t errorCode, id resp) {
if (errorCode != 0) {
_isShowPhoneNum = !isOn;
[switchButton setOn:_isShowPhoneNum animated:YES];
}
}];
}
}
其中_isShowPhoneNum
可以作为成员变量,先初始化为UISwitch
的初始值,当_isShowPhoneNum
与当前值相同时,不需要执行里面的逻辑。
吐槽:这个控件如果手指滑动之后没有抬起继续滑动,就会不断地触发UIControlEventValueChanged
,怎么看都不合理。
本文首发于我的个人博客,欢迎访问:使用UISwitch重复调用UIControlEventValueChanged的问题解决方法