swifferina
swifferina

Reputation: 293

Dynamic UITableview with different objects

I have a tableview with custom cells with UITextField, UIDatePicker, UIPickerView. In my method cellForRowAtIndexPath I set for every row its behavior. But I realized that when I hit the first rows at the top everything is fine, instead when I scroll down the table and change the values on the bottom for example the value I entered on line 7 is inserted on line 8 and so on in the lower lines in practice it creates confusion with the index of the lines when I scroll the table or for example il UITableViewCellAccessoryDisclosureIndicator instead of assigning it to line 9 when reloading the table, the table assigns it to line 2

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    UITextField *text1 = (UITextField *)[cell viewWithTag:100];
    UILabel *text2 = (UILabel *)[cell viewWithTag:200];
    text1.text = [valuesArray objectAtIndex:indexPath.row];
    text2.text = [titlesArray objectAtIndex:indexPath.row];

    switch (indexPath.row) {
        case 0:  
            {
                text1.delegate = self;
                text1.tag = indexPath.row;
            }
            break;

        case 1: 
            {
                activityPicker = [[UIPickerView alloc] init];
                activityPicker.delegate = self;
                activityPicker.tag = indexPath.row;
                text1.delegate = self;
                text1.inputView  = activityPicker;
            }
            break;

        case 2: 
            {
                datePicker = [[UIDatePicker alloc] init];
                datePicker.datePickerMode = UIDatePickerModeDate;
                [datePicker addTarget:self action:@selector(onDatePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
                text1.delegate = self;
                text1.inputView = datePicker;
                datePicker.tag = indexPath.row;
            }
            break;

        case 3: 
            {
                datePicker = [[UIDatePicker alloc] init];
                datePicker.datePickerMode = UIDatePickerModeTime;
                [datePicker addTarget:self action:@selector(onDatePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
                text1.delegate = self;
                text1.inputView = datePicker;
                datePicker.tag = indexPath.row;
                NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                [dateFormatter setDateFormat:@"HH:mm"];
                [datePicker setDate: [dateFormatter dateFromString:text1.text]];
            }
            break;

        case 4:  
            {
                activityPicker = [[UIPickerView alloc] init];
                activityPicker.delegate = self;
                activityPicker.tag = indexPath.row;
                NSString *km = [text1.text substringToIndex:[text1.text length]-3];
                int numkm = [km intValue] - 1;
                [activityPicker selectRow:numkm inComponent:0 animated:YES];
                text1.delegate = self;
                text1.inputView  = activityPicker;
            }
            break;

        case 5: 
            {
                activityPicker = [[UIPickerView alloc] init];
                activityPicker.delegate = self;
                activityPicker.tag = indexPath.row;
                text1.delegate = self;
                text1.inputView = activityPicker;
            }
            break;

        case 6: 
            {
                activityPicker = [[UIPickerView alloc] init];
                activityPicker.delegate = self;
                activityPicker.tag = indexPath.row;
                if ([text1.text isEqualToString:[animalsArray objectAtIndex:0]])
                    [activityPicker selectRow:0 inComponent:0 animated:YES];
                else
                    [activityPicker selectRow:1 inComponent:0 animated:YES];

                text1.delegate = self;
                text1.inputView = activityPicker;
            }
            break;

        case 7:  
                text1.delegate = self;
                text1.tag = indexPath.row;
            }
            break;

        case 8:  
            {
                activityPicker = [[UIPickerView alloc] init];
                activityPicker.delegate = self;
                activityPicker.tag = indexPath.row;
                if ([text1.text isEqualToString:[privacyArray objectAtIndex:0]])
                    [activityPicker selectRow:0 inComponent:0 animated:YES];
                else
                    [activityPicker selectRow:1 inComponent:0 animated:YES];

                text1.delegate = self;
                text1.inputView = activityPicker;
            }
            break;

        case 9:  
        {
            text1.enabled = NO;
            cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        }
            break;

        default:
            break;
    }

    return cell;
}

Upvotes: 0

Views: 46

Answers (1)

meaning-matters
meaning-matters

Reputation: 22946

Your problem is using the same cell identifier "Cell" for all rows. This results in cells that you have already configured for a certain row to be reloaded & reused again for another row.

Assuming you have just these 10 cell designs, you could do:

NSString*        identifier = [NSString stringWithFormat: @"Cell-%d", indexPath.row];
UITableViewCell* cell       = [tableView dequeueReusableCellWithIdentifier:identifier
                                                              forIndexPath:indexPath];

In this way, dequeueReusableCellWithIdentifier will only return the cell that was created earlier for the current indexPath.

Upvotes: 2

Related Questions