UIswitch в ячейке таблицы используется повторно

У меня проблема с uiswitch в моем UITableViewCell, когда я меняю значение переключателя в определенной ячейке, которая принадлежит определенному разделу. Все остальные ячейки разделов, имеющие одинаковые inexPath.row, изменяются. Пожалуйста помоги ?

Вот мой код метода cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    //UISwitch *switchview = nil ;

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



    }


    UISwitch *switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
    CGRect switchFrame = switchController.frame;
    NSString *str = [[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
    NSLog(@"string in cell%@", str);


    //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 ];
    [addSubview:switchController];


    if ([[[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row ]isEqualToString:@"ON"])
 {
        switchController.on=YES;
 }
    else
    {
        switchController.on=NO;
    }


    return cell;

}

А вот SwitchChangedEvent:

-(void)switchChanged:(UISwitch *)sender
{
    UITableViewCell *cell = (UITableViewCell *)[sender 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];

}

person Alanoud Aldrees    schedule 25.04.2013    source источник
comment
У вас есть вопрос?   -  person matt    schedule 25.04.2013
comment
Как выглядит код в switchChanged:?   -  person jszumski    schedule 25.04.2013
comment
@jszumski вот оно:   -  person Alanoud Aldrees    schedule 25.04.2013
comment
@jszumski Я добавляю это в свой пост. ЗАРАНЕЕ СПАСИБО   -  person Alanoud Aldrees    schedule 25.04.2013
comment
@matt YES Когда я меняю uiswitch в tableviewcell, он меняется во всех ячейках с одинаковым indexPath.row, хотя я их не менял? ты понял мою мысль? БЛАГОДАРЮ ВАС   -  person Alanoud Aldrees    schedule 25.04.2013


Ответы (3)


У вас есть две основные проблемы:

  1. Этот код неверен:

      [cell addSubview:switchController ];
    

    Никогда не добавляйте в ячейку подвид; добавьте его только в ячейку contentView.

  2. Вы добавляете переключатель каждый раз через cellForRowAtIndexPath:. Но эти клетки используются повторно. Таким образом, некоторые ячейки уже имеют переключатель. Таким образом, вы добавляете много переключателей в некоторые ячейки.

person matt    schedule 25.04.2013
comment
СПАСИБО за ваш быстрый ответ, это много значит .. Но не могли бы вы дать мне подробную информацию о том, как решить пункт № 2? Я буду очень признателен, ВЫ БУДЕТЕ СПАСАТЬ ЖИЗНЬ - person Alanoud Aldrees; 26.04.2013
comment
Вы уже проверяете, является ли это девственной ячейкой с if (cell == nil). Это условие также требует добавления переключателя. Таким образом, если ячейка не равна нулю, вы точно знаете, что в ней есть переключатель. - person matt; 26.04.2013
comment
Возможно, вам будет полезно прочитать главу моей книги на эту тему: apeth.com/iOSBook/ch21 .html#_table_view_cells - person matt; 26.04.2013
comment
спасибо, Мэтт. Но я попытался поместить свой код в первый if (cell == nil), и он не работает :( - person Alanoud Aldrees; 26.04.2013
comment
Я не говорю, что все, что вы хотите, произойдет только потому, что вы делаете то, что я сказал. Но я говорю, что то, что вы делали, было неправильно, как я описал. - person matt; 26.04.2013

Как уже указывалось другими, вы добавляете несколько переключателей в каждую ячейку. ФТФИ:

UISwitch *switchController = nil;
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:CellIdentifier];
    switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
    switchController.tag = 'swch';
    CGRect switchFrame = switchController.frame;
    //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];
}
else 
{
    switchController = (UISwitch*)[cell.contentView viewWithTag: 'swch'];
    NSAssert(switchController != nil, @"how?");
}

NSString *str = [[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
NSLog(@"string in cell%@", str);

switchController.on = [str isEqualToString:@"ON"];

return cell;
person maroux    schedule 26.04.2013
comment
Я бы настоятельно не рекомендовал switchController.tag = 'swch'. см.: stackoverflow.com/questions/7755202/ - person Jeffery Thomas; 26.04.2013
comment
@JefferyThomas Приятно знать. Хотя, помогите мне понять, почему это плохая идея в данном конкретном случае? Я не вижу здесь проблем с переносимостью. - person maroux; 26.04.2013
comment
int x = 'xxxx' - это неопределенное поведение в стандарте C (GCC и LLVM имеют для него поведение, определяемое реализацией). Настоящая проблема, с которой я столкнулся, заключается в том, что он скрывает значение тега. Тег представляет собой число, а не последовательность из 4 символов. - person Jeffery Thomas; 26.04.2013
comment
В контексте iOS-приложения, созданного с использованием gcc/llvm, все должно быть в порядке :) Теги в целом очень плохи, поскольку у них нет семантики, возможны конфликты, а обслуживание — головная боль. Мне нравятся 4-символьные коды, потому что это хороший способ уменьшить некоторые из этих проблем. Я бы сказал, что swch имеет большее значение, чем 1, вы не согласны? Перечисление, определяющее все теги, является лучшим решением. - person maroux; 26.04.2013

Если вы посмотрите, я думаю, вы обнаружите, что вы строите несколько коммутаторов и на каждой ячейке.

По мере повторного использования ячеек вы добавляете новый переключатель, но не удаляете старый. Я думаю, что это может быть по крайней мере частью причины вашей проблемы.


ОБНОВЛЕНИЕ

Думаю, я бы справился с этим немного иначе, чем другие. Думаю, @AlanoudAldrees будет проще удалить старый переключатель.

if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:CellIdentifier];
}
else
{
    for (UIView *view in cell.subviews)
        if ([view isKindOfClass:[UISwitch class]])
            [view removeFromSuperview];
}
person Jeffery Thomas    schedule 25.04.2013
comment
Не могли бы вы объяснить больше? Потому что я тоже думаю, что это моя проблема СПАСИБО - person Alanoud Aldrees; 26.04.2013