滚动UITableview会更改UIButton,UITableview滚动问题的图像

时间:2013-01-18 14:41:11

标签: iphone ios objective-c xcode

我正在做的是,我有一个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 个答案:

答案 0 :(得分:4)

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

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

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

可能会解决您的问题:)

答案 1 :(得分: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];
    }
}

答案 2 :(得分: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中的对象计数必须与tableView中的单元格数相同。

答案 3 :(得分: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;
}