向上或向下滚动时uiduwitch在uitableviewcell中重置?

时间:2013-04-26 14:09:34

标签: ios objective-c uitableview uiswitch

我在UISwitch内的UITableViewCell有问题。当我更改一个开关的值然后向上或向下滚动所有开关都搞砸了。我使用一个数组来存储每个开关的状态,因为它们每次都可以重复使用。

以下是cellForRowAtIndexPath方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];


    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:@"Cell"];

    }

    UISwitch *switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
    CGRect switchFrame = switchController.frame;
   [switchController setOn:YES animated:NO];
    //set its x and y value, this you will have to determine how to space it on the left side
    switchFrame.origin.x = 50.0f;
    switchFrame.origin.y = 10.0f;
    switchController.frame = switchFrame;


    [switchController addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
    [cell addSubview:switchController ];

    UILabel *label ;

    label=(UILabel *)[cell viewWithTag:1];
    NSString *value = [[mainArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    label.text = value;
    label.textAlignment = NSTextAlignmentRight;
    label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;


    //This for persist switch state when scroll up or down
    if ([[[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row ]isEqualToString:@"ON"])
    {
       switchController.on=YES;


    }
    else 
    {
       switchController.on=NO;


    }

       return cell;   
}

这是SwitchChanged事件:

-(void)switchChanged:(UISwitch *)sender
{
    UITableViewCell *cell = (UITableViewCell *)[[sender superview] superview];
    NSIndexPath *index=[mainTableView indexPathForCell:cell];

    if (sender.on)
    {

        [[self.SwitchArray objectAtIndex:index.section] replaceObjectAtIndex:index.row withObject:@"ON"];
        NSString *word= [[self.mainArray objectAtIndex:index.section ] objectAtIndex:index.row];

    }
    else
    {
        //call the first array by section
        [[self.SwitchArray objectAtIndex:index.section] replaceObjectAtIndex:index.row withObject:@"OFF"];
         NSString *word= [[self.mainArray objectAtIndex:index.section ] objectAtIndex:index.row];

   }

    [padFactoids setObject:[NSKeyedArchiver archivedDataWithRootObject:SwitchArray] forKey:@"savedArray"];
    [padFactoids synchronize];

}

我非常感谢你的帮助。

3 个答案:

答案 0 :(得分:1)

在你的头文件中声明一个NSMutableArray,我们将它命名为 switchStates

在viewDidLoad中,根据开关数分配内存并添加字符串“OFF”的对象:

switchStates = [[NSMutableArray alloc] init];
for (int i; i <= switchesArray.count; i++) {
    [switchStates addObject:@"OFF"];
}

在触发开关时运行的方法中:

NSString *theSwitchPosition = [NSString stringWithFormat:@"%@", switchControl.on ? @"ON" : @"OFF"];
[switchStates replaceObjectAtIndex:aPath.row withObject:theSwitchPosition];

之后,在创建开关的方法中:

if ([[switchStates objectAtIndex:indexPath.row] isEqualToString:@"ON"]) {
    mySwitch.on = YES;
} else {
    mySwitch.on = NO;
}

这对我有用,祝你好运..

答案 1 :(得分:0)

每次tableView请求单元格时,您都在创建一个新的开关。您只想为每个单元创建一次开关:

UISwitch *switchController;

 if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:@"Cell"];

    switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
    CGRect switchFrame = switchController.frame;
    [switchController setOn:YES animated:NO];
    //set its x and y value, this you will have to determine how to space it on the left side
    switchFrame.origin.x = 50.0f;
    switchFrame.origin.y = 10.0f;
    switchController.frame = switchFrame;

    [switchController addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
    [cell.contentView addSubview:switchController ];

    switchController.tag = 123; //Arbitrary number...can be anything 
}
else {
    switchController = (UISwitch *)[cell.contentView viewWithTag:123];
}

//Now set the switch state according to your data model array

将子视图添加到单元格的contentView而不是单元格本身也是一种更好的做法。

答案 2 :(得分:0)

我不确定这是否会导致您的问题,但肯定会引起其他相关问题。

每当一个单元格移出屏幕并出现下一个单元格时,刚刚移出屏幕的单元格将被重复使用。 但是每次向单元格添加一个新的开关对象。你最好只在cell==nil块内创建它们。给它一个标签并使用标签在重新使用时获取对象,就像对标签对象一样。