2013-01-18 173 views
3

我正在做的是,我有一个UITableview,我添加了UIButton作为自定义视图。我正在给每个按钮添加标签,并在操作方法中收到标签。当我按下按钮时,它会改变所选和未选按钮的图像,但是当我滚动它时,它会回到正常状态。UITableview的滚动更改UIButton的图像,UITableview滚动问题

这是在指数法我的行单元格

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]; 
    } 
} 
+0

你有没有想过如何解决这个问题?我现在有同样的问题。 – Foo

回答

4

注:此代码为每行数据的创建小区(未重用小区)

你只需要改变的描述,可能有助于你

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

可能会解决你的问题:)

+0

谢谢......非常感谢。自从8小时以来我就这样做了,现在我完成了。真的非常感谢您 –

+1

请记住,随着您的表的增长,此解决方案可能会导致性能问题。最好的解决方案是让数据源管理您的状态,这样您仍然可以保持单元重用性能。 – nebs

+0

@Nebs - 当用户有很长的数据时会创建问题...但是我还在*我的答案中添加了* NOTE *(*它不会重用'UITableViewCell' *)它会为每行创建单元格 – iPatel

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; 
} 
+0

尝试过它,但它没有解决问题,在滚动它再次将图像更改为正常状态 –

2

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

每调用一次,您都会重新初始化您的按钮并将图像重置为following.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]; 
    } 
} 
+0

您能否建议您在哪里撰写该声明? –

+0

@Prateeksharma我用一些示例代码更新了我的答案(它没有经过测试,只是为了给你一个想法)。 – nebs

+0

用数组也试过这种方式,但是当我滚动时它又移除了当前状态并将其置于正常状态 –

1

当我从代码理解你创建的UIButton每当UITableView的询问小区。在这两种情况下,如果你创建一个新的单元格或者你使用了一个新的单元格。然后,您每创建一个按钮,再创建一个按钮。移动按钮创建到细胞创造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的计数相同。

+0

[self tableviewCellWithReuseIdentifierFollowing:CellIdentifier] ;这是你实现的地方。 – 2014-09-01 09:38:30