2012-05-11 71 views
0

我在寫一個簡單的核對錶應用程序。我有兩個UIViewControllers。第一個在UITableView中顯示清單。我使用UIBarButtonItem將第二個視圖推入堆棧以添加新任務。所有的任務都保存在一個數組中。UITableView中單元格的問題

除了一件事,一切都很好。

如果我進入編輯模式並從表格視圖中刪除一個項目,該項目從表格視圖和數組中刪除 - 這部分似乎工作正常。但是,刪除項目後,如果我點擊欄按鈕項目添加新任務,我遇到了問題。

我的NSLogs告訴我新的項目被添加到數組中,但是當我返回到表格視圖時,刪除的項目顯示出來而不是新的項目。表視圖似乎是重新使用出隊單元格(不確定)。

我在做什麼錯?

CLCheckListViewController.m

#import "CLCheckListViewController.h" 
#import "CLTaskFactory.h" 
#import "CLTaskStore.h" 
#import "CLAddTaskViewController.h" 

@implementation CLCheckListViewController 
{ 
    __weak IBOutlet UITableView *checkList; 
} 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     // add five sample tasks 
     CLTaskFactory *task1 = [[CLTaskFactory alloc] init]; 
     [task1 setTaskName:@"Task 1"]; 
     [task1 setDidComplete:NO]; 
     [[CLTaskStore sharedStore] addTask:task1]; 

     CLTaskFactory *task2 = [[CLTaskFactory alloc] init]; 
     [task2 setTaskName:@"Task 2"]; 
     [task2 setDidComplete:NO]; 
     [[CLTaskStore sharedStore] addTask:task2]; 

     CLTaskFactory *task3 = [[CLTaskFactory alloc] init]; 
     [task3 setTaskName:@"Task 3"]; 
     [task3 setDidComplete:NO]; 
     [[CLTaskStore sharedStore] addTask:task3]; 

     CLTaskFactory *task4 = [[CLTaskFactory alloc] init]; 
     [task4 setTaskName:@"Task 4"]; 
     [task4 setDidComplete:NO]; 
     [[CLTaskStore sharedStore] addTask:task4]; 

     CLTaskFactory *task5 = [[CLTaskFactory alloc] init]; 
     [task5 setTaskName:@"Task 5"]; 
     [task5 setDidComplete:NO]; 
     [[CLTaskStore sharedStore] addTask:task5]; 
    } 
    return self; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [checkList reloadData]; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // create edit button 
    [[self navigationItem] setLeftBarButtonItem:[self editButtonItem]]; 

    // create title 
    [[self navigationItem] setTitle:@"Checklist"]; 

    // create add guest button 
    UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(pushAddTask)]; 
    [[self navigationItem] setRightBarButtonItem:bbi]; 
} 

- (void)pushAddTask 
{ 
    CLAddTaskViewController *advk = [[CLAddTaskViewController alloc] init]; 
    [[self navigationController] pushViewController:advk animated:YES]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [[[CLTaskStore sharedStore] allTasks] count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [checkList dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 

     // put the tasks into the cell 
     [[cell textLabel] setText:[NSString stringWithFormat:@"%@", [[[CLTaskStore sharedStore] allTasks] objectAtIndex:[indexPath row]]]]; 

     // put the checkbox into the cell's accessory view 
     UIButton *checkBox = [UIButton buttonWithType:UIButtonTypeCustom]; 
     checkBox = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [checkBox setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal]; 
     [checkBox setImage:[UIImage imageNamed:@"checkbox-checked.png"] forState:UIControlStateSelected]; 
     checkBox.frame = CGRectMake(0, 0, 30, 30); 
     checkBox.userInteractionEnabled = YES; 
     [checkBox addTarget:self action:@selector(didCheckTask:) forControlEvents:UIControlEventTouchDown]; 
     cell.accessoryView = checkBox; 
    } 
    return cell; 
} 

- (void)didCheckTask:(UIButton *)button 
{ 
    CGPoint hitPoint = [button convertPoint:CGPointZero toView:checkList]; 
    hitIndex = [checkList indexPathForRowAtPoint:hitPoint]; 

    task = [[[CLTaskStore sharedStore] allTasks] objectAtIndex:[hitIndex row]]; 

    if (task.didComplete) { 
     task.didComplete = NO; 
    } else { 
     task.didComplete = YES; 
    } 

    NSInteger taskCount = [[[CLTaskStore sharedStore] allTasks] count]; 
    for (int i = 0; i < taskCount; i++) { 
     NSLog(@"%@, status: %@", [[[CLTaskStore sharedStore] allTasks] objectAtIndex:i], [[[[CLTaskStore sharedStore] allTasks] objectAtIndex:i] didComplete][email protected]"YES":@"NO"); 
    } 

    // toggle checkbox 
    button.selected = !button.selected; 
} 

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

    // set editing mode 
    if (editing) { 
     self.navigationItem.title = @"Edit Checklist"; 
     [checkList setEditing:YES]; 
    } else { 
     self.navigationItem.title = @"Checklist"; 
     [checkList setEditing:NO]; 
    } 
} 

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
              forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // remove task 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 

     // remove task from CLTaskStore 
     task = [[[CLTaskStore sharedStore] allTasks] objectAtIndex:[indexPath row]]; 
     [[CLTaskStore sharedStore] removeTask:task]; 

     // remove guest from table view 
     [checkList deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 

     // reload table view 
     //[checkList reloadData]; 
    } 
} 

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 
{ 
    [[CLTaskStore sharedStore] moveTaskAtIndex:[sourceIndexPath row] toIndex:[destinationIndexPath row]]; 
} 

@end 

CLAddTaskViewController.m

#import "CLAddTaskViewController.h" 
#import "CLTaskFactory.h" 
#import "CLTaskStore.h" 

@implementation CLAddTaskViewController 

    - (void)viewDidLoad 
    { 
     [[self navigationItem] setTitle:@"Add Task"]; 
    } 

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

     // clear first responder 
     [[self view] endEditing:YES]; 

     // create new task 
     CLTaskFactory *newTask = [[CLTaskFactory alloc] init]; 
     [newTask setTaskName:[newTaskName text]]; 

     // add new guest to RCGuestStore 
     [[CLTaskStore sharedStore] addTask:newTask]; 
    } 

    @end 

CLAddTaskFactory.m

#import "CLTaskFactory.h" 

@implementation CLTaskFactory 

@synthesize taskName; 

- (void)setDidComplete:(BOOL)dc 
{ 
    didComplete = dc; 
} 

- (BOOL)didComplete 
{ 
    return didComplete; 
} 

- (NSString *)description 
{ 
    // override the description 
    NSString *descriptionString = [[NSString alloc] initWithFormat:@"%@", taskName]; 
    return descriptionString; 
} 

@end 

CLAddTaskStore.m

#import "CLTaskStore.h" 
#import "CLTaskFactory.h" 
#import "CLCheckListViewController.h" 

@implementation CLTaskStore 

+ (id)allocWithZone:(NSZone *)zone 
{ 
    return [self sharedStore]; 
} 

+ (CLTaskStore *)sharedStore 
{ 
    static CLTaskStore *sharedStore = nil; 
    if (!sharedStore) { 
     sharedStore = [[super allocWithZone:nil] init]; 
    } 
    return sharedStore; 
} 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     allTasks = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

- (NSMutableArray *)allTasks 
{ 
    return allTasks; 
} 

- (void)addTask:(CLTaskFactory *)task 
{ 
    [allTasks addObject:task]; 
    NSLog(@"Task added: %@", task); 
} 

- (void)removeTask:(CLTaskFactory *)task 
{ 
    // remove the item for the deleted row from the store 
    [allTasks removeObjectIdenticalTo:task]; 

    NSInteger taskCount = [allTasks count]; 
    NSLog(@"Removed: %@, there are now %d remaining tasks, they are:", task, taskCount); 
    for (int i = 0; i < taskCount; i++) { 
     NSLog(@"%@, status: %@", [[[CLTaskStore sharedStore] allTasks] objectAtIndex:i], [[[[CLTaskStore sharedStore] allTasks] objectAtIndex:i] didComplete][email protected]"YES":@"NO"); 
    } 
} 

- (void)moveTaskAtIndex:(int)from toIndex:(int)to 
{ 
    if (from == to) { 
     return; 
    } 

    CLTaskFactory *task = [allTasks objectAtIndex:from]; 
    [allTasks removeObjectAtIndex:from]; 
    [allTasks insertObject:task atIndex:to]; 
} 

@end 

感謝您的幫助!

回答

1

表視圖似乎被重用取出的細胞

這正是它;它儘可能重用細胞。如果您有足夠的項目可以使表格視圖滾動,您也會看到同樣的問題。

-tableView:cellForRowAtIndexPath:中,無論dequeueReusableCellWithIdentifier:是否返回單元格,您都必須將單元格設置爲顯示給定行索引的正確內容。

基本上是:

  • 如果-dequeueReusableCellWithIdentifier:返回nil,創建一個新的單元格並添加複選框按鈕即可。

  • 然後設置單元格文本,並從-dequeueReusableCellWithIdentifier:

1

達倫正確返回上無論是新小區或單元格中的按鈕狀態。如果你看看你的代碼在這裏:

if (!cell) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 

    // put the tasks into the cell 
    [[cell textLabel] setText:[NSString stringWithFormat:@"%@", [[[CLTaskStore sharedStore] allTasks] objectAtIndex:[indexPath row]]]]; 

    // put the checkbox into the cell's accessory view 
    UIButton *checkBox = [UIButton buttonWithType:UIButtonTypeCustom]; 
    checkBox = [UIButton buttonWithType:UIButtonTypeCustom]; 
    [checkBox setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal]; 
    [checkBox setImage:[UIImage imageNamed:@"checkbox-checked.png"] forState:UIControlStateSelected]; 
    checkBox.frame = CGRectMake(0, 0, 30, 30); 
    checkBox.userInteractionEnabled = YES; 
    [checkBox addTarget:self action:@selector(didCheckTask:) forControlEvents:UIControlEventTouchDown]; 
    cell.accessoryView = checkBox; 
} 

你只設置了小區if(cell == nil) 更改您的代碼

if (!cell) { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
} 
// put the tasks into the cell 
[[cell textLabel] setText:[NSString stringWithFormat:@"%@", [[[CLTaskStore sharedStore] allTasks] objectAtIndex:[indexPath row]]]]; 

// put the checkbox into the cell's accessory view 
UIButton *checkBox = [UIButton buttonWithType:UIButtonTypeCustom]; 
checkBox = [UIButton buttonWithType:UIButtonTypeCustom]; 
[checkBox setImage:[UIImage imageNamed:@"checkbox.png"] forState:UIControlStateNormal]; 
[checkBox setImage:[UIImage imageNamed:@"checkbox-checked.png"] forState:UIControlStateSelected]; 
checkBox.frame = CGRectMake(0, 0, 30, 30); 
checkBox.userInteractionEnabled = YES; 
[checkBox addTarget:self action:@selector(didCheckTask:) forControlEvents:UIControlEventTouchDown]; 
cell.accessoryView = checkBox; 
+0

感謝您的補充解釋。非常有幫助,現在我更瞭解它。 – mySilmaril

相關問題