我有一个左侧检查按钮的表格视图。对于前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
答案 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复制和粘贴它。
我很欣赏您想要解决您正在开发的应用程序的问题,但除非您了解某些内容的工作方式或原因,否则您将难以尝试修复其他人的代码。
如果您有具体问题,请在评论中提问,我会尽力回答!