3

我正在做的是,我有一个UITableview并且我添加UIButton为自定义视图。我为每个按钮提供标签,并在操作方法中收到标签。当我按下按钮时,它会更改选定和未选定按钮的图像,但是当我滚动它时,它将进入正常状态。

这是我在索引方法中的行单元格

static NSString *CellIdentifier = @"Cell4";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier];
}
followingButton = [UIButton buttonWithType:UIButtonTypeCustom];
[followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside];
[followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];
followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0);
[cell.contentView addSubview:followingButton];
NSLog(@"row--%d",indexPath.row);
followingButton.tag=indexPath.row;
NSLog(@"followingButton.tag--%d",followingButton.tag);
[self configureCellFollowing:cell forIndexPath:indexPath];
return cell;
}

==================

//Here is the action method

-(void)followingButtonpressed:(id)sender
{
    NSLog(@"sender tag --%d",[sender tag]);
    UIButton *btnPly = (UIButton *)sender;
    if([btnPly isSelected])
    {
        [btnPly setSelected:NO];
        [btnPly setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];
    }
    else
    {
        [btnPly setSelected:YES];
        [btnPly setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal];
    }
}
4

4 回答 4

4

注意:此代码为每行数据创建单元格(不重用单元格)

您只需要按照描述进行更改,可能对您有帮助

NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row];

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

可能会解决你的问题:)

于 2013-01-18T15:00:41.480 回答
2

您的按钮“重置”的原因是因为 tableView:cellForRowAtIndexPath 被多次调用(每当一个单元格即将可见时)。

每次调用它时,您都会重新初始化按钮并将图像重置为 following12.png(默认状态)。这就是为什么当您滚动按钮时出现重置的原因。

您不能依赖单元格本身来保存状态,因为单元格每次都会被重置。您需要将状态移动到其他地方(例如在数组实例变量中)。然后,当您必须在 tableView:cellForRowAtIndexPath 中配置一个新单元格时,您可以将其初始化为正确的状态(基于数组)。

因此,创建一个名为 myStateArray (或其他)的 NSMutableArray 实例变量来存储您的按钮状态,那么您的 cellForRowAtIndexPath 应该看起来更像:

static NSString *CellIdentifier = @"Cell4";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier];
}
followingButton = [UIButton buttonWithType:UIButtonTypeCustom];
[followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside];

// -- Fetch the state from your array
BOOL buttonPressed = [[self.myStateArray objectAtIndex:indexPath.row] boolValue];

// -- Initialize the button state correctly
[followingButton setSelected:buttonPressed];
if (buttonPressed) {
    [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];
} else {
    [followingButton setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal];
}



followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0);
[cell.contentView addSubview:followingButton];
NSLog(@"row--%d",indexPath.row);
followingButton.tag=indexPath.row;
NSLog(@"followingButton.tag--%d",followingButton.tag);
[self configureCellFollowing:cell forIndexPath:indexPath];
return cell;
}

然后在您的按钮按下确保保存状态:

-(void)followingButtonpressed:(id)sender
{
    // -- Save the state
    [self.myStateArray insertObject:[NSNumber numberWithBool:[btnPly isSelected]] atIndex:[sender tag]];

    NSLog(@"sender tag --%d",[sender tag]);
    UIButton *btnPly = (UIButton *)sender;
    if([btnPly isSelected])
    {
        [btnPly setSelected:NO];
        [btnPly setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];
    }
    else
    {
        [btnPly setSelected:YES];
        [btnPly setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal];
    }
}
于 2013-01-18T14:55:45.613 回答
1

正如我从代码中了解到的那样,每次 UITableView 要求单元格时,您都会创建 UIButton 。在这两种情况下,如果您创建一个新单元格或使用出列单元格。然后,您每次在已创建的按钮上创建并添加一个按钮。将按钮创建移动到单元格创建if所以你的cellForRowAtIndexPath方法应该看起来像

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell4";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier];
        followingButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside];
        [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];
        followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0);
        [cell.contentView addSubview:followingButton];
    }
    NSLog(@"row--%d",indexPath.row);
    followingButton.tag=indexPath.row;
    NSLog(@"followingButton.tag--%d",followingButton.tag);
    [self configureCellFollowing:cell forIndexPath:indexPath];
    return cell;
}

但这不会是您问题的竞争解决方案。您可能知道 UITableView 使用“可重用”单元格来减少系统内存使用量。它仅使用当前需要显示的单元格数量。因此,在具有 100 个单元格的表格中,它实际上会创建大约 10 个。并且所有这些单元格都不会存储所有按下/未按下按钮的正确状态。为了实现正确的行为,您必须拒绝使用标签并改用一些模型逻辑。最简单的方法 - NSMutableArray,您将在其中存储按钮状态。在 followingButtonpressed:方法中,您将正确的对象设置为 YES/NO,然后cellForRowAtIndexPath您将读取此值。检查下面的代码

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell4";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier];
        followingButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside];
        [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];
        followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0);
        [cell.contentView addSubview:followingButton];

        BOOL isSelected = [[statesArray objectAtIndex:btnPly.tag] boolValue];
        [self setState:isSelected forButton:followingButton];
    }
    NSLog(@"row--%d",indexPath.row);
    followingButton.tag=indexPath.row;
    NSLog(@"followingButton.tag--%d",followingButton.tag);
    [self configureCellFollowing:cell forIndexPath:indexPath];
    return cell;
}

-(void)followingButtonpressed:(id)sender
{
    NSLog(@"sender tag --%d",[sender tag]);
    UIButton *btnPly = (UIButton *)sender;

    BOOL isSelected = [[statesArray objectAtIndex:btnPly.tag] boolValue];
    [statesArray replaceObjectAtIndex:btnPly.tag withObject:[NSNumber numberWithBool:!isSelected]];

    if(isSelected)
    {
        [self setState:NO forButton:btnPly];
    }
    else
    {
        [self setState:YES forButton:btnPly];
    }
}

- (void) setState:(BOOL)state forButton:(UIButton *)button
{
    if(state)
    {
        [button setSelected:NO];
        [button setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];
    }
    else
    {
        [button setSelected:YES];
        [button setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal];
    }
}

statesArray在哪里

NSMutableArray *statesArray = [NSMutableArray new];

你必须在你班级的某个地方创建和初始化它。中的对象statesArray计数必须与单元格 int tableView 的计数相同。

于 2013-01-18T15:20:06.147 回答
0

这是因为每次滚动时都会调用此代码

[followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];

所以现在检查

static NSString *CellIdentifier = @"Cell4";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier];

followingButton = [UIButton buttonWithType:UIButtonTypeCustom];
[followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside];

[followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal];

followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0);
[cell.contentView addSubview:followingButton];

[self configureCellFollowing:cell forIndexPath:indexPath];
}
return cell;
}
于 2013-01-18T14:48:31.197 回答