uitableview复选框重置问题

时间:2011-04-04 06:34:50

标签: iphone ios4

我的uitableview有20行,显示了许多食物。

每个食品都有一个复选框。

我的问题是:如果我选中复选框的第一行然后滚动表格视图,则复选标记会重置。

我该如何解决这个问题?请帮帮我。

代码更新:

- (IBAction)buttonAction:(id)sender
{
  if ([sender isKindOfClass:[UIButton class]])
  {
    UIButton *checkboxButton = (UIButton*)sender;

    checkboxButton.selected = !checkboxButton.selected;

    NSIndexPath *indexPath = [self.myTableView indexPathForCell:(UITableViewCell*)[[checkboxButton superview] superview]];

    BOOL selected = [[selectedArray objectAtIndex:[indexPath row]] boolValue];

    [selectedArray replaceObjectAtIndex:[indexPath row] withObject:[NSNumber numberWithBool:!selected]];

      if (!self.checkedIndexPaths)
          checkedIndexPaths = [[NSMutableSet alloc] init];

    if(selected == NO)
    {
          NSLog(@"cvbcvbNO BOOL value");    // ...

        //  If we are checking this cell, we do
        [self.checkedIndexPaths addObject:indexPath];
    }
    else
    {
      NSLog(@"cvbvbYES BOOL VALURE");

        //  If we are checking this cell, we do
        [self.checkedIndexPaths removeObject:indexPath];
    }



  }
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

  static NSString *CellIdentifier = @"Celhgl";

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

  profileName = [appDelegate.sentItemsList objectAtIndex:indexPath.row];

  if (cell == nil)
  {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

        cb = [[UIButton alloc] initWithFrame:CGRectMake(5,10, unselectedImage.size.width, unselectedImage.size.height)];
        [cb setImage:unselectedImage forState:UIControlStateNormal];
        [cb setImage:selectedImage forState:UIControlStateSelected];
        [cb addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchDown];
        [cell.contentView addSubview:cb];

        for (NSIndexPath *path in self.checkedIndexPaths)
        {
            NSLog(@"%d",path.row);

            NSLog(@"%d",indexPath.row);

           if (path.row == indexPath.row)
          {
            NSLog(@"dfd %d",indexPath.row);
          }
        }

   }

    if ( tableView == myTableView )
    {
        titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 0, 150, 35)];
        titleLabel.font = [UIFont boldSystemFontOfSize:13];
        titleLabel.textColor = [UIColor blackColor];   
        [cell.contentView addSubview:titleLabel];
        NSString *subjectData = [profileName.sent_subject stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
        [titleLabel setText:[NSString stringWithFormat: @"%@ ", subjectData]];
    }

    return cell;
}

2 个答案:

答案 0 :(得分:5)

将已检查的项目保存在数据源中。

我通常会将所选对象的NSIndexPaths保存在NSMutableSet中 在tableView:cellForRowAtIndexPath:中,我检查索引路径是否是具有所选索引路径的集合的一部分。

@interface RootViewController : UITableViewController {
    NSMutableSet *set;
}

// implementation:

- (void)viewDidLoad {
    [super viewDidLoad];
    set = [[NSMutableSet alloc] init];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell.
    cell.textLabel.text = [NSString stringWithFormat:@"Cell %d", indexPath.row];
    if ([set containsObject:indexPath]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([set containsObject:indexPath]) {
        [set removeObject:indexPath];
    }
    else {
        [set addObject:indexPath];
    }
    [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

答案 1 :(得分:5)

正在发生的事情是UITableView正在回收UITableViewCells以节省内存。这意味着当您向下滚动列表时,UITableView会将单元格从表格的顶部取出并重新使用它们以显示以后的项目,因此当您向上滚动它们时它们会丢失状态。

您可以通过保留NSMutableSet个已检查的indexPath来纠正此问题。当用户检查某个项目时,您可以将其indexPath添加到此集合中。然后在cellForRowAtIndexPath中,您可以确保检查项目是否在您选中的项目集中。

<强>更新

以下是一个如何运作的粗略示例:

# MyTableView.h

@interface MyTableView: UITableView
<UITableViewDataSource, UITableViewDelegate>
{
  NSMutableSet *checkedIndexPaths;
}

@property (nonatomic, retain) NSMutableSet *checkedIndexPaths;

@end

然后

# MyTableView.m
#import "MyTableView.h"

@implementation MyTableView

@synthesize checkedIndexPaths;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  //  Normal layout stuff goes here...
  //  ***Add code to make sure the checkbox in this cell is unticked.***

  for (NSIndexPath *path in self.checkedIndexPaths)
  {
    if (path.section == indexPath.section && path.row == indexPath.row)
    {
      //  ***We found a matching index path in our set of checked index paths, so we need to show this to the user by putting a tick in the check box, for instance***
    }
  }
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  //  Normal stuff to handle visual checking/unchecking of row here

  //  Lazy-load the mutable set
  if (!self.checkedIndexPaths)
    checkedIndexPaths = [[NSMutableSet alloc] init];

  //  If we are checking this cell, we do
  [self.checkedIndexPaths addObject:indexPath];

  //  If we are unchecking, just enumerate over the items in checkedIndexPaths and remove the one where the row and section match.
}

@end

这只是骨架代码而且没有经过测试,但希望它能为你提供一个jist。