UIButton在滚动时在UITableViewCell中重用

时间:2015-08-06 18:03:28

标签: ios objective-c uitableview uibutton

在我的UITableView中,有标题单元格和标准单元格。每个标准单元格都添加了一个复选框(UIButton),使用以下两种方法。

调用以下方法创建每个UITableViewCell

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

static NSString *tableIdentifier = @"activityIdentifier";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];

// HEADER ROWS
if (indexPath.row == 0 || indexPath.row == 5 || indexPath.row == 10 || indexPath.row == 15 || indexPath.row == 20 || indexPath.row == 25 || indexPath.row == 30) {

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];
        NSLog(@"Yeaa!");
    }

    cell.textLabel.text = [activityArray objectAtIndex:indexPath.row];
    cell.textLabel.textColor = [UIColor blackColor];
    cell.textLabel.font = [UIFont fontWithName:@"Aliquam" size:13.0f];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.backgroundColor = [UIColor whiteColor];
    static int a = 20.0f;
    tableView.rowHeight = a;

} else {
    // STANDARD ROWS
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];
        NSLog(@"Standard cell is nil");

    }

    cell.textLabel.text = [activityArray objectAtIndex:indexPath.row];
    cell.backgroundColor = [UIColor clearColor];
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.font = [UIFont fontWithName:@"Aliquam" size:20.0f];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    static int b = 44.0f;
    tableView.rowHeight = b;
}

// CREATE CHECK BOXES IN STANDARD ROWS
if (indexPath.row == 1) {
    [self createRoleCheckbox:actMondayMorning];
    [cell addSubview:actMondayMorning];
} else if (indexPath.row == 2) {
    [self createRoleCheckbox:actMondayAfternoon];
    [cell addSubview:actMondayAfternoon];
} else if (indexPath.row == 3) {
    [self createRoleCheckbox:actMondayEvening];
    [cell addSubview:actMondayEvening];
} else if (indexPath.row == 4) {
    [self createRoleCheckbox:actMondayNight];
    [cell addSubview:actMondayNight];
} else if (indexPath.row == 6) {
    [self createRoleCheckbox:actTuesdayMorning];
    [cell addSubview:actTuesdayMorning];
} else if (indexPath.row == 7) {
    [self createRoleCheckbox:actTuesdayAfternoon];
    [cell addSubview:actTuesdayAfternoon];
} else if (indexPath.row == 8) {
    [self createRoleCheckbox:actTuesdayEvening];
    [cell addSubview:actTuesdayEvening];
} else if (indexPath.row == 9) {
    [self createRoleCheckbox:actTuesdayNight];
    [cell addSubview:actTuesdayNight];
} else if (indexPath.row == 11) {
    [self createRoleCheckbox:actWednesdayMorning];
    [cell addSubview:actWednesdayMorning];
} else if (indexPath.row == 12) {
    [self createRoleCheckbox:actWednesdayAfternoon];
    [cell addSubview:actWednesdayAfternoon];
} else if (indexPath.row == 13) {
    [self createRoleCheckbox:actWednesdayEvening];
    [cell addSubview:actWednesdayEvening];
} else if (indexPath.row == 14) {
    [self createRoleCheckbox:actWednesdayNight];
    [cell addSubview:actWednesdayNight];
} else if (indexPath.row == 16) {
    [self createRoleCheckbox:actThursdayMorning];
    [cell addSubview:actThursdayMorning];
} else if (indexPath.row == 17) {
    [self createRoleCheckbox:actThursdayAfternoon];
    [cell addSubview:actThursdayAfternoon];
} else if (indexPath.row == 18) {
    [self createRoleCheckbox:actThursdayEvening];
    [cell addSubview:actThursdayEvening];
} else if (indexPath.row == 19) {
    [self createRoleCheckbox:actThursdayNight];
    [cell addSubview:actThursdayNight];
} else if (indexPath.row == 21) {
    [self createRoleCheckbox:actFridayMorning];
    [cell addSubview:actFridayMorning];
} else if (indexPath.row == 22) {
    [self createRoleCheckbox:actFridayAfternoon];
    [cell addSubview:actFridayAfternoon];
} else if (indexPath.row == 23) {
    [self createRoleCheckbox:actFridayEvening];
    [cell addSubview:actFridayEvening];
} else if (indexPath.row == 24) {
    [self createRoleCheckbox:actFridayNight];
    [cell addSubview:actFridayNight];
} else if (indexPath.row == 26) {
    [self createRoleCheckbox:actSaturdayMorning];
    [cell addSubview:actSaturdayMorning];
} else if (indexPath.row == 27) {
    [self createRoleCheckbox:actSaturdayAfternoon];
    [cell addSubview:actSaturdayAfternoon];
} else if (indexPath.row == 28) {
    [self createRoleCheckbox:actSaturdayEvening];
    [cell addSubview:actSaturdayEvening];
} else if (indexPath.row == 29) {
    [self createRoleCheckbox:actSaturdayNight];
    [cell addSubview:actSaturdayNight];
} else if (indexPath.row == 31) {
    [self createRoleCheckbox:actSundayMorning];
    [cell addSubview:actSundayMorning];
} else if (indexPath.row == 32) {
    [self createRoleCheckbox:actSundayAfternoon];
    [cell addSubview:actSundayAfternoon];
} else if (indexPath.row == 33) {
    [self createRoleCheckbox:actSundayEvening];
    [cell addSubview:actSundayEvening];
} else if (indexPath.row == 34) {
    [self createRoleCheckbox:actSundayNight];
    [cell addSubview:actSundayNight];
}

return cell;
}

调用以下方法创建复选框(UIButton):

- (void) createRoleCheckbox:(UIButton *)passedButton {

passedButton.frame = CGRectMake(screenWidth-checkboxDiameter-(checkboxInset/2), (checkboxInset/2), checkboxDiameter, checkboxDiameter);

[passedButton setImage:checkboxImageUnselected forState:UIControlStateNormal];
[passedButton setImage:checkboxImageSelected forState:UIControlStateSelected];

if (passedButton == actMondayMorning)
    [passedButton addTarget:self action:@selector(actMondayMorningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actMondayAfternoon)
    [passedButton addTarget:self action:@selector(actMondayAfternoonPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actMondayEvening)
    [passedButton addTarget:self action:@selector(actMondayEveningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actMondayNight)
    [passedButton addTarget:self action:@selector(actMondayNightPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actTuesdayMorning)
    [passedButton addTarget:self action:@selector(actTuesdayMorningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actTuesdayAfternoon)
    [passedButton addTarget:self action:@selector(actTuesdayAfternoonPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actTuesdayEvening)
    [passedButton addTarget:self action:@selector(actTuesdayEveningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actTuesdayNight)
    [passedButton addTarget:self action:@selector(actTuesdayNightPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actWednesdayMorning)
    [passedButton addTarget:self action:@selector(actWednesdayMorningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actWednesdayAfternoon)
    [passedButton addTarget:self action:@selector(actWednesdayAfternoonPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actWednesdayEvening)
    [passedButton addTarget:self action:@selector(actWednesdayEveningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actWednesdayNight)
    [passedButton addTarget:self action:@selector(actWednesdayNightPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actThursdayMorning)
    [passedButton addTarget:self action:@selector(actThursdayMorningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actThursdayAfternoon)
    [passedButton addTarget:self action:@selector(actThursdayAfternoonPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actThursdayEvening)
    [passedButton addTarget:self action:@selector(actThursdayEveningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actThursdayNight)
    [passedButton addTarget:self action:@selector(actThursdayNightPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actFridayMorning)
    [passedButton addTarget:self action:@selector(actFridayMorningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actFridayAfternoon)
    [passedButton addTarget:self action:@selector(actFridayAfternoonPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actFridayEvening)
    [passedButton addTarget:self action:@selector(actFridayEveningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actFridayNight)
    [passedButton addTarget:self action:@selector(actFridayNightPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSaturdayMorning)
    [passedButton addTarget:self action:@selector(actSaturdayMorningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSaturdayAfternoon)
    [passedButton addTarget:self action:@selector(actSaturdayAfternoonPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSaturdayEvening)
    [passedButton addTarget:self action:@selector(actSaturdayEveningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSaturdayNight)
    [passedButton addTarget:self action:@selector(actSaturdayNightPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSundayMorning)
    [passedButton addTarget:self action:@selector(actSundayMorningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSundayAfternoon)
    [passedButton addTarget:self action:@selector(actSundayAfternoonPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSundayEvening)
    [passedButton addTarget:self action:@selector(actSundayEveningPressed) forControlEvents:UIControlEventTouchUpInside];
else if (passedButton == actSundayNight)
    [passedButton addTarget:self action:@selector(actSundayNightPressed) forControlEvents:UIControlEventTouchUpInside];

}

此代码在每行中正确创建复选框。

然而,当我滚动浏览我的应用时,UIButton s副本会随机出现在标题单元格中。

此外,如果我单击一个按钮,将其置于选定状态,当我滚动时,其他按钮也会随机也被选中状态,即使我没有按下它们。

简而言之,UIButton正在重复使用。我怎么能发生这种情况?

所有帮助表示赞赏。

4 个答案:

答案 0 :(得分:0)

首先,将您的按钮添加到单元格的contentView,然后清除contentView,在添加按钮之前删除所有内容。如果有效,请告诉我。

答案 1 :(得分:0)

您需要重构代码。

对于您创建的每种结构不同类型的单元格,您应该具有不同的标识符。

如果标题单元格的元素不同于"标准"单元格,让您的cellForRowAtIndexPath方法首先确定这是否是标题行。如果是标题行,请使用标题单元格的ID调用dequeueReusableCellWithIdentifier。如果没有,请使用标准"标准"细胞

这样,如果有一个正确的类型,你只能获得一个可回收的单元格,并且当你想要一个标准的时候,你永远不会得到一个标题单元格"细胞

答案 2 :(得分:0)

首先,我强烈建议不要创建“标题”单元格,而是使用部分代替您不需要为特定的indexPath行创建条件。

另一方面,您不清楚如何创建按钮,但据我所知,您每次在屏幕上显示单元格时都会添加一个按钮,而且&# 39;不清楚indexPath.rows如何传递给createRoleCheckbox方法,因为它只需要一个UIButton作为参数。

在任何情况下,我都不认为根据行创建按钮是个好主意,我创建一个按钮,然后更改选择器(以及我认为的标题)取决于行,如下所示:

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

    static NSString *tableIdentifier = @"activityIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];

    // Since you switched to section they are all standard rows now
    if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];
            NSLog(@"Standard cell is nil");

    }

    UIButton *cellButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    cellButton.frame = CGRectMake(0.0, 0.0, 150.0, 30.0);
    [cell addSubview:cellButton];

    cell.textLabel.text = [activityArray objectAtIndex:indexPath.row];
    cell.backgroundColor = [UIColor clearColor];
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.font = [UIFont fontWithName:@"Aliquam" size:20.0f];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    static int b = 44.0f;
    tableView.rowHeight = b;


    if (indexPath.row == 1) {
         [cellButton addTarget:self action:@selector(appropiateMethod) forControlEvents:UIControlEventTouchUpInside];
         [cellButton setTitle:@"Appropiate Title" forState:UIControlStateNormal];
    } else if (indexPath.row == 2) {
         [cellButton addTarget:self action:@selector(appropiateMethod) forControlEvents:UIControlEventTouchUpInside];
         [cellButton setTitle:@"Appropiate Title" forState:UIControlStateNormal];
    } else if (indexPath.row == 3) {
         [cellButton addTarget:self action:@selector(appropiateMethod) forControlEvents:UIControlEventTouchUpInside];
         [cellButton setTitle:@"Appropiate Title" forState:UIControlStateNormal];
    } ...

    return cell;
}

这种方法都会使createRoleCheckbox方法完全不必要。

希望这有帮助!

答案 3 :(得分:0)

我已经解决了我的问题。这是一个贫民窟解决方案,我敢肯定纯粹主义者可能会对它提出问题(说实话,它可能会以某种方式导致内存问题,但这不应该是我的应用程序的问题,因为视图控制器只是简单地打开)。

首先,我将UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];替换为UITableViewCell *cell

然后我将cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];替换为cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];。我的代码在技术上略有不同,但这是我所做的精髓。我想我会停止重复使用按钮的代码,好吧,停止重复使用按钮。希望这有助于未来的某个人,并且不会导致比解决更多的问题。