美文网首页iOS技巧学习_JMiOS学习笔记iOS学习开发
使用UISwitch重复调用UIControlEventValu

使用UISwitch重复调用UIControlEventValu

作者: vinnyxiong | 来源:发表于2016-03-29 09:25 被阅读1651次

    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的问题解决方法

    相关文章

      网友评论

      本文标题:使用UISwitch重复调用UIControlEventValu

      本文链接:https://www.haomeiwen.com/subject/zrqslttx.html