Флажок, устанавливающий другие флажки, когда один из них установлен

#iphone #objective-c #uitableview #nsuserdefaults

#iPhone #objective-c #uitableview #nsuserdefaults

Вопрос:

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

Checkbox.m

 - (void)checkImages {
    NSUInteger tag = [self tag];
    BOOL val = [[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"%i", tag]];
    if (val == YES) {
        [self setImage:[UIImage imageNamed:@"checkbox-pressed.png"] forState:UIControlStateNormal];
        [[NSUserDefaults standardUserDefaults] setBool:NO forKey:[NSString stringWithFormat:@"%i", tag]];
    }
    else if (val == NO) {
        [self setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal];
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:[NSString stringWithFormat:@"%i", tag]];
    }
    [[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([[[[event allTouches] anyObject] view] tag] == [self tag]) {
        [self checkImages];
    }
}
  

RootViewController:

 - (void)viewDidLoad
{


    //This will set a solid background color
    self.tableView.backgroundColor = [UIColor blackColor];
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

    if (_checkboxArray == nil) {
        [self setItemArray:[[NSMutableArray alloc] init]];
    }
    if (_cellTextArray == nil) {
        [self setCellTextArray:[[NSMutableArray alloc] init]];
    }
    if (![[NSUserDefaults standardUserDefaults] boolForKey:kFL]) {
        NSMutableArray *custArr = [[NSMutableArray alloc] init];
        for (int i = 0; i < [_checkboxArray count]; i   ) {
            CheckBox *c = (CheckBox *)[_checkboxArray objectAtIndex:i];
            [c setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal];
            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:[NSString stringWithFormat:@"%i", [c tag]]];
            [custArr addObject:c];
        }
        [_checkboxArray release];
        [_checkboxArray setArray:custArr];
        [custArr release];

        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kFL];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
 for (int i = 0; i < [textLabelArray count]; i  ) {
        NSDictionary *dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:[textLabelArray objectAtIndex:i], [detailTextArray objectAtIndex:i], [cornLabelArray objectAtIndex:i], nil] forKeys:[NSArray arrayWithObjects:@"textLabel", @"detailTextLabel", @"cornerLabel", nil]];
        [_cellTextArray addObject:dict];
        [dict release];
    }
    for (int i = 0; i < [_cellTextArray count]; i  ) {
        CheckBox*btn = [[CheckBox alloc] init];
        [btn setFrame:CGRectMake(0, 10, 40, 40)];
        [btn setTag:i];
        UIImage *img = [UIImage imageNamed:[[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"%i", btn.tag]] ? @"checkbox.png":@"checkbox-pressed.png"];
        [btn setImage:img forState:UIControlStateNormal];
        [_checkboxArray addObject:btn];
        [btn release];
    }
    [self.tableView reloadData];
    [super viewDidLoad];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"CustomCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    CheckBox *btn;
    UILabel *lab, *dlabl, *cornerLabel;
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        btn = (CheckBox *)[_checkboxArray objectAtIndex:indexPath.row];
        [cell.contentView addSubview:btn];
        //I added this code:
        cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:12.0];
        cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
        cell.textLabel.numberOfLines = 3; // 0 means no max.


        UIImageView* img = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gradient7.png"]] autorelease];
        [cell setBackgroundView:img];

        lab = [[[UILabel alloc] initWithFrame:CGRectMake(40, 18, cell.contentView.frame.size.width-15, 22)] autorelease];
        [lab setBackgroundColor:[UIColor clearColor]];
        [lab setTextColor:[UIColor whiteColor]];
        [lab setAdjustsFontSizeToFitWidth:YES];
        [lab setTextAlignment:UITextAlignmentLeft];
        [lab setTag:kTEXT_LABEL_TAG];
        [cell.contentView addSubview:lab];

        dlabl = [[[UILabel alloc] initWithFrame:CGRectMake(5, 54, cell.contentView.frame.size.width- 1, 22)] autorelease];
        [dlabl setTextColor:[UIColor colorWithRed:1.0 green:0.80 blue:0.0 alpha:1.0]];
        [dlabl setBackgroundColor:[UIColor clearColor]];
       // [dlabl setAdjustsFontSizeToFitWidth:YES];
        [dlabl setTextAlignment:UITextAlignmentLeft];
        [dlabl setTag:kDETAIL_TEXT_LABEL_TAG];
        [dlabl setFont:[UIFont systemFontOfSize:[lab font].pointSize - 3]];
        [cell.contentView addSubview:dlabl];

        cornerLabel = [[[UILabel alloc] initWithFrame:CGRectMake(cell.contentView.frame.size.width - 40, 19, 40, 20)] autorelease];
        [cornerLabel setTextColor:[UIColor whiteColor]];
        //[cornerLabel setFont:[UIFont systemFontOfSize:12]];
        [cornerLabel setAdjustsFontSizeToFitWidth:YES];
        [cornerLabel setBackgroundColor:[UIColor clearColor]];
        [cornerLabel setTextAlignment:UITextAlignmentCenter];
        [cornerLabel setTag:kCORNER_TEXT_LABEL_TAG];
        [cell.contentView addSubview:cornerLabel];
        [cornerLabel setAdjustsFontSizeToFitWidth:YES];
    }
    else {
        lab = (UILabel *)[[cell contentView] viewWithTag:kTEXT_LABEL_TAG];
        dlabl = (UILabel *)[[cell contentView] viewWithTag:kDETAIL_TEXT_LABEL_TAG];
        cornerLabel = (UILabel *)[[cell contentView] viewWithTag:kCORNER_TEXT_LABEL_TAG];
        btn = (CheckBox *)[[cell contentView] viewWithTag:kBTN_TAG];
    }
    NSDictionary *dict = [_cellTextArray objectAtIndex:indexPath.row];
    lab.text = [dict objectForKey:@"textLabel"];
    dlabl.text = [dict objectForKey:@"detailTextLabel"];
    cornerLabel.text = [dict objectForKey:@"cornerLabel"];
    if ([[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"%d", indexPath.row]] == NO) {
        [btn setImage:[UIImage imageNamed:@"checkbox-pressed.png"] forState:UIControlStateNormal];
    }else {
        [btn setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal];
    }
    return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 80.0f;
}
  

Комментарии:

1. Был ли мой ответ полезным для вас? Если да, пожалуйста, примите это, если нет, пожалуйста, предоставьте дополнительную информацию.

Ответ №1:

Вы используете tableView dequeueReusableCellWithIdentifier:CellIdentifier] . Это хорошо, но это означает, что в вашем табличном представлении у вас есть только столько ячеек, сколько вы можете видеть. Когда вы прокручиваете и ячейка покидает экран с одного конца, она будет использована повторно и снова появится на экране с другого конца. И, конечно, ячейка по-прежнему содержит тот же флажок, поэтому, если он был установлен, когда он покидал экран, он все равно будет установлен, если нет, то этого не будет.

Решение этой проблемы должно быть довольно простым. В вашем tableView:(UITableView *)tableView cellForRowAtIndexPath: вы уже заполнили ячейку в соответствии с элементом, который должен там отображаться ( lab.text = [dict objectForKey:@"textLabel"]; и так далее). Итак, все, что вам нужно, это сохранить состояние флажков для каждого элемента в вашем tableview и восстановить его там.

Надеюсь, это поможет!

Комментарии:

1. Хорошо, пока у меня это работает, но в каждую ячейку добавляется несколько кнопок. Как я могу предотвратить это

2. Не могли бы вы объяснить это подробнее? Вы имеете в виду, что при загрузке повторно используемой ячейки добавляется новый флажок? Если это так, это не происходит автоматически, поэтому проверьте свой код, чтобы узнать, куда вы их добавляете, и не делайте этого 🙂

3. Или, если вам нужно их добавить, удалите старый с помощью removeFromSuperview.