一些数据添加后复选标记重复....当我检查

时间:2015-08-31 22:02:20

标签: ios

我有一个左侧检查按钮的表格视图。对于前6个数据,它运作良好。当我在我的表视图中添加另外三个数据之后,当我检查我的第一个数据时,我的数据也会得到检查。当我检查一个数据时,其他一些数据也会以复选标记重复.....  我正在使用核心数据....如果有人能回答这个......

  @interface ViewController ()
{

    NSDateFormatter *formatter;
}

@property (strong) NSMutableArray *notes;
@end

@implementation ViewController
@synthesize tableView;
@synthesize addButton;
@synthesize catefetchedResultsController;


- (NSManagedObjectContext *)managedObjectContext {
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    if ([delegate performSelector:@selector(managedObjectContext)]) {
        context = [delegate managedObjectContext];
    }
    return context;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.navigationItem.title = @"My Notes";

    tableView.dataSource = self;
    tableView.delegate = self;
    [self.view addSubview:tableView];

    formatter = [[NSDateFormatter alloc] init];
    formatter.doesRelativeDateFormatting = YES;
    formatter.locale = [NSLocale currentLocale];
    formatter.dateStyle = NSDateFormatterShortStyle;
    formatter.timeStyle = NSDateFormatterNoStyle;

             CATransition *animation = [CATransition animation];
            [animation setDuration:2.0];
            [animation setType:kCATransitionPush];
        [animation setSubtype:kCATransitionFromTop];

        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]];

        [[addButton layer] addAnimation:animation forKey:@"SwitchToDown"];


}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Fetch the devices from persistent data store
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Notes"];

    NSError *error = nil;
    self.notes = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];

    NSSortDescriptor *titleSorter= [[NSSortDescriptor alloc] initWithKey:@"mod_time" ascending:NO];

    [self.notes sortUsingDescriptors:[NSArray arrayWithObject:titleSorter]]
    ;

    NSLog(@"Your Error - %@",error.description);

    [tableView reloadData];
}



#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return self.notes.count;
}

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

    //UIButton *testButton;
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];


        UIButton *testButton = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];


        [testButton setImage:[UIImage imageNamed:@"oval"] forState:UIControlStateNormal];

        [testButton setImage:[UIImage imageNamed:@"tick"] forState:UIControlStateSelected];

        [testButton addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];

        [cell addSubview:testButton];
        [cell setIndentationLevel:1];
        [cell setIndentationWidth:45];





    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    }


    // Configure the cell...
        NSManagedObject *note = [self.notes objectAtIndex:indexPath.row];

        NSDate *date = [note valueForKey:@"mod_time"];

        NSString *dateString = [formatter stringFromDate:date];


        cell.textLabel.text = [note valueForKey:@"title"];



        cell.detailTextLabel.text = dateString;




    return cell;

}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    //cell.textLabel.font = [UIFont fontNamesForFamilyName:@"Avenir"];
    cell.textLabel.font = [UIFont fontWithName:@"Avenir" size:19.0];


    cell.detailTextLabel.font=[UIFont fontWithName:@"Avenir" size:15.0];

}

-(void)buttonTouched:(id)sender




{

        UIButton *btn = (UIButton *)sender;

        if( [[btn imageForState:UIControlStateNormal] isEqual:[UIImage imageNamed:@"oval"]])
        {

            [btn setImage:[UIImage imageNamed:@"tick"] forState:UIControlStateNormal];

        }
        else
        {
            [btn setImage:[UIImage imageNamed:@"oval"] forState:UIControlStateNormal];
                    }
    }

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];

        [tableView deselectRowAtIndexPath:indexPath animated:YES];


}
- (IBAction)addButtonPressed:(id)sender {
    AddNoteViewController *addNoteVC = [AddNoteViewController new];

    // to remove unused warning....
#pragma unused (addNoteVC)

}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

- (void)tableView:(UITableView *)cTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObjectContext *context = [self managedObjectContext];

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete object from database
        [context deleteObject:[self.notes objectAtIndex:indexPath.row]];

        NSError *error = nil;
        if (![context save:&error]) {
            NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]);
            return;
        }

        // Remove device from table view
        [self.notes removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}
- (IBAction)btnClick:(id)sender {
}
@end

2 个答案:

答案 0 :(得分:1)

好吧,我看到你的代码,是的,问题是可重用性只是改变这个,它将解决你的问题

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

//UIButton *testButton;

    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];


    UIButton *testButton = [[UIButton alloc]initWithFrame:CGRectMake(5, 5, 40, 40)];


    [testButton setImage:[UIImage imageNamed:@"oval"] forState:UIControlStateNormal];

    [testButton setImage:[UIImage imageNamed:@"tick"] forState:UIControlStateSelected];

    [testButton addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside];

    [cell addSubview:testButton];
    [cell setIndentationLevel:1];
    [cell setIndentationWidth:45];





cell.selectionStyle = UITableViewCellSelectionStyleNone;




// Configure the cell...
    NSManagedObject *note = [self.notes objectAtIndex:indexPath.row];

    NSDate *date = [note valueForKey:@"mod_time"];

    NSString *dateString = [formatter stringFromDate:date];


    cell.textLabel.text = [note valueForKey:@"title"];



    cell.detailTextLabel.text = dateString;




return cell;

}

答案 1 :(得分:0)

当细胞被重复使用时,你必须准备它们以便重复使用,否则你的按钮会在另一行设置时显示上一个图像。

您必须重置按钮的(选定)状态以匹配其当前行的状态。

您可以在tableView:cellForRowAtIbdexPath:或单元格的prepareForReuse方法中执行此操作。

<强>更新

执行此操作的首选方法是子类UITableViewCell并添加UIButton属性。这比向单元格(contentView,而不是)视图添加按钮要好得多。

在您的自定义单元格中,它看起来像:

@interface ButtonCell : UITableViewCell
{
    @property (weak) IBOutlet UIButton *toggleButton;
}

然后,您可以在其ButtonCell类的故事板自定义单元格之间连接IBOutlets和IBActions。

然后按属性访问单元格中的按钮是一件简单的事情:

[cell.toggleButton setImage:[UIImage imageNamed:@"oval"] forState:UIControlStateNormal];
[cell.toggleButton setImage:[UIImage imageNamed:@"tick"] forState:UIControlStateSelected];

如果每一行都应该以图像为椭圆形的默认状态开始,那么请务必从tableView:cellForRowAtIndexPath:

调用这些行

这将覆盖从单元格用于的另一行遗留下来的任何先前切换状态,因此当您期望椭圆形时,您将看不到勾号:)

更新2:

由于你有一个自定义单元格,你已经在其上有一个按钮,你不再需要在单元格(内容)视图中创建或添加按钮。因此,旧方法的代码不再适用:

    [cell addSubview:toogleButton]; // <-- remove this

接下来,UITableViewCell没有toggleButton属性。您需要使用您的子类ButtonCell, 具有toggleButton属性。将自定义单元格(您已指定并连接到故事板的动态原型单元格中)出列。

    ButtonCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];

由于该方法始终返回一个单元格,因此您可以删除所有cell == nil条件代码。

现在你有了一个自定义单元格,你可以设置它的图像。

由于cellForIndexPath不是您切换其状态的地方,因此您不希望任何条件代码在椭圆和刻度之间进行更改。

您现在的方法是尝试通过更改显示的图像,使按钮跟踪其自己的滴答/椭圆状态。 但是当单元格滚出屏幕时,单元格的按钮将被重用。这意味着该按钮无法跟踪其上一行是否已勾选。

每当你需要记住某个行是否被勾选时,你想要在模型中的一个数组中跟踪它。

因此,根据模型有条件地设置自定义按钮的图像。

    if ([self.noteState objectAtIndex:indexPath.row]) // An array of flags indicating whether a row is checked or not
    {
        [cell.toggleButton setImage:[UIImage imageNamed:@"tick"] forState:UIControlStateSelected];
    }
    else
    {
        [cell.toggleButton setImage:[UIImage imageNamed:@"oval"] forState:UIControlStateSelected];
    }

现在,您的表行将被适当地检查。

由于您的模型已检查状态,您还需要对buttonTouched代码进行现代化,以便类似地更新模型并切换按钮。

我把它作为锻炼给你。如果到目前为止你已经理解了其他所有内容,那么应用你学到的东西就不会有任何问题。

您的目标应该是学习和理解代码块的作用,而不是简单地从StackOverflow复制和粘贴它。

我很欣赏您想要解决您正在开发的应用程序的问题,但除非您了解某些内容的工作方式或原因,否则您将难以尝试修复其他人的代码。

如果您有具体问题,请在评论中提问,我会尽力回答!