2012-05-11 9 views
0

간단한 체크리스트 앱을 쓰고 있습니다. 두 개의 UIViewController 있습니다. 첫 번째는 체크리스트를 UITableView에 표시합니다. UIBarButtonItem을 사용하여 새 작업을 추가하기 위해 두 번째 뷰를 스택으로 푸시합니다. 모든 작업은 배열로 저장됩니다.UITableView의 셀 관련 문제

모든 것이 효과가 있습니다.

편집 모드로 전환하고 테이블보기에서 항목을 삭제하면 해당 항목이 테이블보기와 배열에서 제거됩니다.이 부분은 정상적으로 작동하는 것 같습니다. 그러나 항목을 삭제 한 후에 바 버튼 항목을 눌러 새 작업을 추가하면 문제가 발생합니다.

NSLog는 새 항목이 배열에 추가되었다고 알려주지 만 테이블보기로 돌아 오면 삭제 된 항목이 새 항목 대신 표시됩니다. 테이블 뷰는 대기열에서 제외 된 셀을 재사용하는 것으로 보입니다 (확실하지 않음).

내가 뭘 잘못하고 있니?

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 
,174,

도움 주셔서 감사합니다.

답변

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) { 
    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

덕분에 코드를 변경 셀 if(cell == nil)을 설정. 매우 도움이되었고, 나는 그것을 더 잘 이해합니다. – mySilmaril

관련 문제