滚动 UITableView 时单选按钮未被选中

Radio buttons get unselected while scrolling UITableView

我在 UITableView 上有两个单选按钮 Cell.I 在向下滚动 UITableView 时我可以 select 其中一个,但是当我向上滚动 tableview 时,所有单选按钮都被取消select。滚动后我也想保留它们 selected 但我做不到......所以请任何有解决方案的人帮助我。谢谢

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell";
    customCell *cell = (customCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
    {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];

    }

    leftBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
    leftBtnclick.tag=999;
    [leftBtnclick setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
    [leftBtnclick setImage:[UIImage imageNamed:@"checked.png"] forState:UIControlStateSelected];

    if (screenHeight == 667)
    {
        [leftBtnclick setFrame:CGRectMake(50, 59, 30, 30)];
     }
    else if(screenHeight == 480)
    {
        [leftBtnclick setFrame:CGRectMake(50, 40, 30, 30)];

    }

    [leftBtnclick addTarget:self action:@selector(leftTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [cell.leftOptBtn addTarget:self action:@selector(leftTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:leftBtnclick];

    rightBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
    rightBtnclick.tag=1000;
    [rightBtnclick setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
    [rightBtnclick setImage:[UIImage imageNamed:@"checked.png"] forState:UIControlStateSelected];

    if (screenHeight == 667)
    {
       [rightBtnclick setFrame:CGRectMake(180, 59, 30, 30)];
    }
    else if(screenHeight == 480)
    {
        [leftBtnclick setFrame:CGRectMake(50, 40, 30, 30)];

    }

    [rightBtnclick setFrame:CGRectMake(180, 59, 30, 30)];
    [rightBtnclick addTarget:self action:@selector(rightTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [cell.rightOptBtn addTarget:self action:@selector(rightTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:rightBtnclick];

    cell.numberLbl.text = [numberArray objectAtIndex:indexPath.row];
    cell.questionLbl.text = [questionArray objectAtIndex:indexPath.row];
    [cell.leftOptBtn setTitle:[leftOptionArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];
    [cell.rightOptBtn setTitle:[rightOptionArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];
    return cell;
}

-(void)leftTickBtnClicked:(id)sender
{
    UIButton *leftTickBtn=(UIButton *)sender;
    leftTickBtn.selected=!leftTickBtn.selected;
    for(UIView *vw in [[sender superview]subviews])
    {
        if([vw isKindOfClass:[UIButton class]] && vw.tag==1000)
        {
            UIButton *rightTickBtn=(UIButton *)vw;

            if(leftTickBtn.selected)
            {
                rightTickBtn.selected=NO;
            }
            else
            {
                rightTickBtn.selected=YES;
            }

        }
    }

}

-(void)rightTickBtnClicked:(id)sender
{

    UIButton *rightTickBtn=(UIButton *)sender;
    rightTickBtn.selected=!rightTickBtn.selected;


    for(UIView *vw in [[sender superview]subviews])
    {
        if([vw isKindOfClass:[UIButton class]] && vw.tag==999)
        {
            UIButton *leftTickBtn=(UIButton *)vw;

            if(rightTickBtn.selected)
            {
                leftTickBtn.selected=NO;
            }
            else
            {
                leftTickBtn.selected=YES;
            }

        }
    }


}

您只创建了一个 leftTickBtnrightTickBtn 并在每次创建行时更新它。所以最后无论你用单选按钮做了什么,它只影响到最后一个按钮。

更新您的代码如下:

UIButton *leftBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
leftBtnclick.tag=999+indexPath.row;

UIButton *rightBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
rightBtnclick.tag=1000+indexPath.row;

并实现如下方法:

- (IBAction)leftTickBtnClicked:(UIButton *)sender
{
    sender.selected = TRUE;
    UITableViewCell *cell = [tblAppointment cellForRowAtIndexPath:[NSIndexPath indexPathForRow:1000-sender.tag inSection:0]];

    for (id view in cell.contentView.subviews)
    {
        if ([view isKindOfClass:[UIButton class]])
        {
            // your code
             UIButton *btnRight = (UIButton *)view;
             if (sender.selected == TRUE)
                 btnRight.selected = FALSE;
             else
                 btnRight.selected = TRUE;
        }
    }
}

- (IBAction)rightTickBtnClicked:(UIButton *)sender
{
    sender.selected = TRUE;
    UITableViewCell *cell = [tblAppointment cellForRowAtIndexPath:[NSIndexPath indexPathForRow:999-sender.tag inSection:0]];

    for (id view in cell.contentView.subviews)
    {
        if ([view isKindOfClass:[UIButton class]])
        {
            // your code
             UIButton *btnLeft = (UIButton *)view;
             if (sender.selected == TRUE)
                 btnLeft.selected = FALSE;
             else
                 btnLeft.selected = TRUE;
        }
    }
}

您遇到这个问题是因为可重复使用单元格的工作原理。 当您滚动离开您在单选按钮上进行更改的单元格,然后尝试滚动回该特定行时,可重复使用的单元格 dequeueReusableCellWithIdentifier 不保证它会出列您进行更改的完全相同的单元格并且它很可能会使您未进行任何更改的单元格出队

您需要跟踪 cellForRowAtIndexPath 外部列表中的按钮选择,并将选择重新分配给 cellForRowAtIndexPath 中的单选按钮,就像每次分配单元格文本的想法一样使用 cell.numberLbl.text = [numberArray objectAtIndex:indexPath.row]; 通过在数组

中使用 indexPath.row

请参阅下面代码的修改 [1]、[2] 和 [3](尚未测试,但您明白了)

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier = @"cell";
        customCell *cell = (customCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (cell == nil)
        {
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
            cell = [nib objectAtIndex:0];

        }

        leftBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
        leftBtnclick.tag=999;
        [leftBtnclick setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
        [leftBtnclick setImage:[UIImage imageNamed:@"checked.png"] forState:UIControlStateSelected];

        if (screenHeight == 667)
        {
            [leftBtnclick setFrame:CGRectMake(50, 59, 30, 30)];
         }
        else if(screenHeight == 480)
        {
            [leftBtnclick setFrame:CGRectMake(50, 40, 30, 30)];

        }

        [leftBtnclick addTarget:self action:@selector(leftTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [cell.leftOptBtn addTarget:self action:@selector(leftTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView addSubview:leftBtnclick];

        rightBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
        rightBtnclick.tag=1000;
        [rightBtnclick setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
        [rightBtnclick setImage:[UIImage imageNamed:@"checked.png"] forState:UIControlStateSelected];

        if (screenHeight == 667)
        {
           [rightBtnclick setFrame:CGRectMake(180, 59, 30, 30)];
        }
        else if(screenHeight == 480)
        {
            [leftBtnclick setFrame:CGRectMake(50, 40, 30, 30)];

        }

        [rightBtnclick setFrame:CGRectMake(180, 59, 30, 30)];
        [rightBtnclick addTarget:self action:@selector(rightTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [cell.rightOptBtn addTarget:self action:@selector(rightTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView addSubview:rightBtnclick];

        cell.numberLbl.text = [numberArray objectAtIndex:indexPath.row];
        cell.questionLbl.text = [questionArray objectAtIndex:indexPath.row];
        [cell.leftOptBtn setTitle:[leftOptionArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];
        [cell.rightOptBtn setTitle:[rightOptionArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];


            //[1]Set values for left and right 
    rightTickBtn.selected = [RightTicksArray objectAtIndex:indexPath.row];
    leftTickBtn.selected = [LeftTicksArray objectAtIndex:indexPath.row];
        return cell;
    }

    -(void)leftTickBtnClicked:(id)sender
    {
        UIButton *leftTickBtn=(UIButton *)sender;
        leftTickBtn.selected=!leftTickBtn.selected;
        for(UIView *vw in [[sender superview]subviews])
        {
            if([vw isKindOfClass:[UIButton class]] && vw.tag==1000)
            {
                UIButton *rightTickBtn=(UIButton *)vw;

                if(leftTickBtn.selected)
                {
                    rightTickBtn.selected=NO;
                }
                else
                {
                    rightTickBtn.selected=YES;
                }
//[2]Update RightTickArray At Pos
     [RightTickArray objectAtIndex:indexPath.row] = leftTickBtn.selected;
        }
    }

    }

    -(void)rightTickBtnClicked:(id)sender
    {

        UIButton *rightTickBtn=(UIButton *)sender;
        rightTickBtn.selected=!rightTickBtn.selected;


        for(UIView *vw in [[sender superview]subviews])
        {
            if([vw isKindOfClass:[UIButton class]] && vw.tag==999)
            {
                UIButton *leftTickBtn=(UIButton *)vw;

                if(rightTickBtn.selected)
                {
                    leftTickBtn.selected=NO;
                }
                else
                {
                    leftTickBtn.selected=YES;
                }

    //[3]Update LeftTickArray At Pos
        [LeftTicksArray objectAtIndex:indexPath.row] = leftTickBtn.selected;
                }
            }


    }

我找到了问题的解决方案。当您滚动 tableview 单元格时,UITableView 单元格是可重用的,这就是单选按钮选择消失的原因。所以解决方案是将您的选择存储在一个数组中,在 cellForRowAtIndexPath 中使用该数组。见代码。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"cell";
    customCell *cell = (customCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
    {

        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];

    }

    leftBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
    leftBtnclick.tag=999;
    cell.leftOptBtn.tag=999;
    [leftBtnclick setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
    [leftBtnclick setImage:[UIImage imageNamed:@"checked.png"] forState:UIControlStateSelected];
    [leftBtnclick setFrame:CGRectMake(50, 59, 30, 30)];
    [leftBtnclick addTarget:self action:@selector(leftTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [cell.leftOptBtn addTarget:self action:@selector(leftBtnClicked) forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:leftBtnclick];


    rightBtnclick = [UIButton buttonWithType:UIButtonTypeCustom];
    rightBtnclick.tag=1000;
    cell.rightTickBtn.tag=1000;
    [rightBtnclick setImage:[UIImage imageNamed:@"unchecked.png"] forState:UIControlStateNormal];
    [rightBtnclick setImage:[UIImage imageNamed:@"checked.png"] forState:UIControlStateSelected];
    [rightBtnclick setFrame:CGRectMake(190, 59, 30, 30)];


    [rightBtnclick addTarget:self action:@selector(rightTickBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [cell.rightOptBtn addTarget:self action:@selector(rightBtnClicked) forControlEvents:UIControlEventTouchUpInside];
    [cell.contentView addSubview:rightBtnclick];

    cell.numberLbl.text = [numberArray objectAtIndex:indexPath.row];
    cell.questionLbl.text = [questionArray objectAtIndex:indexPath.row];
    [cell.leftOptBtn setTitle:[leftOptionArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];
    [cell.rightOptBtn setTitle:[rightOptionArray objectAtIndex:indexPath.row] forState:UIControlStateNormal];

    if ([[answerArray objectAtIndex:indexPath.row] isEqualToString:@"YES"])
    {
        leftBtnclick.selected=YES;
        rightBtnclick.selected=NO;

    }
    else if ([[answerArray objectAtIndex:indexPath.row] isEqualToString:@"NO"])
    {
        leftBtnclick.selected=NO;
        rightBtnclick.selected=YES;
    }
    else
    {
        leftBtnclick.selected=NO;
        rightBtnclick.selected=NO;
    }
    return cell;
}



-(void)leftTickBtnClicked:(id)sender
{
    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:questionTable];
    NSIndexPath *indexPath1 = [questionTable indexPathForRowAtPoint:buttonPosition];
    [answerArray replaceObjectAtIndex:indexPath1.row withObject:@"YES"];

    UIButton *leftTickBtn=(UIButton *)sender;
    leftTickBtn.selected=!leftTickBtn.selected;
    for(UIView *vw in [[sender superview]subviews])
    {
        if([vw isKindOfClass:[UIButton class]] && vw.tag==1000)
        {
            UIButton *rightTickBtn=(UIButton *)vw;

            if(leftTickBtn.selected)
            {
                 rightTickBtn.selected=NO;

            }
            else
            {
                rightTickBtn.selected=YES;

            }


        }
    }
    NSLog(@"Answer Array: %@",answerArray);
}

-(void)rightTickBtnClicked:(id)sender
{
    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:questionTable];
    NSIndexPath *indexPath1 = [questionTable indexPathForRowAtPoint:buttonPosition];
    [answerArray replaceObjectAtIndex:indexPath1.row withObject:@"NO"];

    UIButton *rightTickBtn=(UIButton *)sender;
    rightTickBtn.selected=!rightTickBtn.selected;


    for(UIView *vw in [[sender superview]subviews])
    {
        if([vw isKindOfClass:[UIButton class]] && vw.tag==999)
        {
            UIButton *leftTickBtn=(UIButton *)vw;

            if(rightTickBtn.selected)
            {
                leftTickBtn.selected=NO;

            }
            else
            {
                leftTickBtn.selected=YES;

            }

        }
    }
    NSLog(@"Answer Array: %@",answerArray);

}