Showing and hiding UITableViewCell with UISwitch too fast crashes

岁酱吖の 提交于 2019-12-05 06:18:03

Another (more elegant) solution at the problem is this:

I modified the Alan MacGregor - (IBAction)SwitchDidChange:(id)sender method in this way:

- (IBAction)SwitchDidChange:(UISwitch *)source {
     if (_showRows != source.on) {
         NSArray *aryTemp = [[NSArray alloc] initWithObjects:
                    [NSIndexPath indexPathForRow:1 inSection:0],
                    [NSIndexPath indexPathForRow:2 inSection:0],
                    [NSIndexPath indexPathForRow:3 inSection:0],
                    [NSIndexPath indexPathForRow:4 inSection:0],nil];
         [_tblView beginUpdates];
         _showRows = source.on;
         if (_showRows) {
             [_tblView insertSections:aryTemp withRowAnimation:UITableViewRowAnimationFade];
         }
         else {
             [_tblView deleteSections:aryTemp withRowAnimation:UITableViewRowAnimationFade];
         }
         [_tblView endUpdates];
     }
}

The other parts stay unchanged.

Simply set the enabled property of your switch to NO until the updates are done.

I had this issue on mine and the way to avoid the crash is to not explicitly use the uiswitch, instead relay the information into a boolean, heres how I did it.

Add a boolean to the top of your implementation file

bool _showRows = NO;

Update your uiswitch code

- (IBAction)SwitchDidChange:(id)sender {

NSArray *aryTemp = [[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:1 inSection:0],
                    [NSIndexPath indexPathForRow:2 inSection:0],
                    [NSIndexPath indexPathForRow:3 inSection:0],
                    [NSIndexPath indexPathForRow:4 inSection:0],nil];

if (_showRows) {
    _showRows = NO;
    _switch.on = NO;
    [_tblView  deleteRowsAtIndexPaths:aryTemp withRowAnimation:UITableViewRowAnimationTop];
}
else {
    _showRows = YES;
    _switch.on = YES;
    [_tblView insertRowsAtIndexPaths:aryTemp withRowAnimation:UITableViewRowAnimationBottom];
}
}

And finally update your numberOfRowsInSection

- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {

    if (_showRows) {
        return 5;
    }
    else {
        return 1;

    }      
}
return 0;  
}

UIControlEventValueChanged events occur even when a control's value doesn't actually change. so togglePush gets called even when the value of the switch doesn't change. when you quickly toggle the switch, you might not always go from on > off > on > off, etc. it's possible to go off > on > on > off.

so what's happening is that you're getting two ons in a row causing two insertSections one after the other. which is obviously bad.

to fix this, you need to remember what the previous state of the button was (in an ivar, maybe) and only perform the insert (or delete) if the new value (source.on) is different from the previous value.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!