加载多次时,cellForRowAtIndexPath行为不正常

时间:2014-11-28 14:24:54

标签: ios iphone ios7 ios8

我使用以下代码创建了一个带滑动手势的应用。手势应仅适用于特定行。它在第一次装载时工作得很好。从第二次手势功能为每一行工作。

我的代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
GoalDetailsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GoalDetailsCell"];

if(cell == nil)
{
    cell = [[GoalDetailsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"GoalDetailsCell"];
}

NSMutableDictionary *cellData = [self.databaseCall transactionFromDatabase:indexPath.row goalId:self.goalId andStageId:self.stageId];

cell.goalDescription.text = self.goalName;
cell.actionGoalDescription.text = self.goalName;
cell.tipsDescription.text = [cellData objectForKey:@"tipsDescription"];
UIImage *cellImage = [UIImage imageNamed:[cellData objectForKey:@"categoryImage"]];
NSLog(@"%@", [cellData objectForKey:@"cardType"]);

if([[cellData objectForKey:@"cardType"] isEqualToString:@"2"])
{
    UISwipeGestureRecognizer *swipeLeftGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeftMethod:)];
    swipeLeftGesture.direction = UISwipeGestureRecognizerDirectionLeft;
    [cell.cardDetails addGestureRecognizer:swipeLeftGesture];
    [cell.tryThisButton addTarget:self action:@selector(tryThisButtonPressed:) forControlEvents:UIControlEventTouchDown];

    UISwipeGestureRecognizer *swipeRightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRightMethod:)];
    swipeRightGesture.direction = UISwipeGestureRecognizerDirectionRight;
    [cell.actionCardReminder addGestureRecognizer:swipeRightGesture];
    [cell.previousButton addTarget:self action:@selector(previousButtonPressed:) forControlEvents:UIControlEventTouchDown];
    cell.tryThisButton.hidden = NO;
    [cell.tryThisButton setImage:[UIImage imageNamed:@"trythis.jpg"] forState:UIControlStateNormal];
    [cell.actionCardType setImage:[UIImage imageNamed:@"toconsider.jpg"]];
    cell.cardType.image = [UIImage imageNamed:@"toconsider.jpg"];
    cell.cardTypeImage.hidden = YES;
    cell.actionCardGoalName.text = self.goalName;
    cell.actionGoalsImage.image = cellImage;
    cell.actionCardReminder.layer.cornerRadius = 5;
    cell.datePicker.layer.borderWidth = 0.2;
    cell.datePicker.layer.borderColor = [[UIColor grayColor] CGColor];
}
else{
    cell.tryThisButton.hidden = YES;
    cell.cardTypeImage.hidden = NO;
    cell.cardType.image = [UIImage imageNamed:@"goodtoknow.jpg"];
    cell.cardTypeImage.image = [UIImage imageNamed:@"tips.jpg"];
}

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:[cellData objectForKey:@"actionLink"]];
[str addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(0, [str length])];
[str addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:NSMakeRange(0, [str length])];

[cell.reminderSwitch addTarget:self action:@selector(customSwitchChanged:) forControlEvents:UIControlEventValueChanged];
[cell.datePicker addTarget:self action:@selector(datePickerButtonPressed:) forControlEvents:UIControlEventTouchDown];

cell.weburl.attributedText = str;
cell.goalName.text = self.goalName;
cell.goalsImage.image = cellImage;
cell.cardDetails.layer.cornerRadius = 5;
NSLog(@"%d", indexPath.row);

// Configure the cell...
return cell;
}

提前致谢。

2 个答案:

答案 0 :(得分:1)

这是因为您使用dequeueReusableCellWithIdentifier:重复使用单元格进行快速修复,您可以在else语句中明确删除手势识别器,例如:

else {
    cell.tryThisButton.hidden = YES;
    cell.cardTypeImage.hidden = NO;
    cell.cardType.image = [UIImage imageNamed:@"goodtoknow.jpg"];
    cell.cardTypeImage.image = [UIImage imageNamed:@"tips.jpg"];

    // To remove all swipe gestures:
    for (UIGestureRecognizer *recognizer in cell.cardDetails.gestureRecognizers) {
        [cell.cardDetails removeGestureRecognizer:recognizer];
    }
    for (UIGestureRecognizer *recognizer in cell.actionCardReminder.gestureRecognizers) {
        [cell.actionCardReminder removeGestureRecognizer:recognizer];
    }
}

但是我认为有更好的方法来构建代码,因为在重用单元格时,你也基本上将手势识别器分层。我认为你需要找出一种重用你的手势识别器的方法,就像你重复使用其他渠道一样。但是为了快速解决问题,我的解决方案应该可行。

答案 1 :(得分:0)

您已经标记了答案,但仍然是一些代码:

在viewDidLoad中:

[self.tableView registerClass:[GoalDetailsTableViewCell class] forCellWithReuseIdentifier:@"GoalDetailsCell"];
[self.tableView registerClass:[GoalDetailsTableViewCellWithGestures class] forCellWithReuseIdentifier:@"GoalDetailsCellWithGestures”];

并在你的cellForRowAtIndexPath中:

if([[cellData objectForKey:@"cardType"] isEqualToString:@"2"])
{
GoalDetailsTableViewCellWithGestures *cell = [tableView dequeueReusableCellWithIdentifier:@"GoalDetailsCellWithGestures"];
// configure this type of cell (text, gestures, etc)
return cell;
}
else
{
GoalDetailsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GoalDetailsTableViewCell"];
// configure this type of cell (text, etc)
return cell;
}