2013-08-21 1 views
1

정말 고민 중이며 다른 사람이 도울 수 있기를 바랍니다.코어 데이터 저장 후 사용자 정의 셀 레이블 텍스트가 겹칩니다.

코어 데이터를 사용하고 있고 fetchedResultsController를 사용하여 TableView를 채우고 있습니다. 셀 유형의 경우 사용자 지정을 사용하고 있습니다. 상세보기를 보완하는 셀을 선택한 후 필드 중 하나를 변경하고 저장을 눌러 테이블 뷰로 돌아갑니다. 문제는 이전 필드 텍스트가 아직 남아 있고 새 텍스트가 겹쳐져 있다는 것입니다.

- (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]; 

     [self configureCell:cell atIndexPath:indexPath]; 
    } 
    else { 

     // Cells all appear blank if I don't include the following line 
     [self configureCell:cell atIndexPath:indexPath]; 

     Games *game = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

     UILabel *nwOpp = (UILabel *)[cell.contentView viewWithTag:401]; 
     NSLog(@"nwOpp:%@", nwOpp.text); 
     nwOpp.text = [NSString stringWithFormat:@"%@", game.opponents.name]; 

     UILabel *nwDate = (UILabel *)[cell.contentView viewWithTag:501]; 
     NSLog(@"Date:%@", nwDate.text); 
     nwDate.text = [NSString stringWithFormat:@"%@ - %@" , [dateFormatter stringFromDate: game.date] , game.location]; 

     UIImageView *nwImg2 = (UIImageView *)[cell.contentView viewWithTag:201]; 
     nwImg2.image = game.opponents.image; 
    } 

    return cell; 
} 

    - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { 

    Games *game = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

    CGRect imageFrame = CGRectMake(70, 2, 20, 20); 
    UIImageView *customImage = [[UIImageView alloc] initWithFrame:imageFrame]; 
    [customImage setContentMode:UIViewContentModeScaleAspectFill]; 
    customImage.clipsToBounds = YES; 
    customImage.image = game.teams.image; 
    customImage.tag = 101; 
    [cell.contentView addSubview:customImage]; 

    CGRect imageFrame2 = CGRectMake(230, 2, 20, 20); 
    UIImageView *customImage2 = [[UIImageView alloc] initWithFrame:imageFrame2]; 
    [customImage2 setContentMode:UIViewContentModeScaleAspectFill]; 
    customImage2.clipsToBounds = YES; 
    customImage2.image = game.opponents.image; 
    customImage2.tag = 201; 
    [cell.contentView addSubview:customImage2]; 

    CGRect teamFrame = CGRectMake(0, 18, 140, 24); 
    UILabel *teamLabel = [[UILabel alloc] initWithFrame:teamFrame]; 
    teamLabel.font = [UIFont boldSystemFontOfSize:14]; 
    teamLabel.text = [NSString stringWithFormat:@"%@", game.teams.name]; 
    teamLabel.textAlignment = NSTextAlignmentCenter; 
    teamLabel.tag = 301; 
    [cell.contentView addSubview:teamLabel]; 

    CGRect versusFrame = CGRectMake(140, 18, 20, 24); 
    UILabel *versusLabel = [[UILabel alloc] initWithFrame:versusFrame]; 
    versusLabel.font = [UIFont boldSystemFontOfSize:16]; 
    versusLabel.text = @"vs"; 
    versusLabel.textAlignment= NSTextAlignmentCenter; 
    [cell.contentView addSubview:versusLabel]; 

    CGRect oppFrame = CGRectMake(160, 18, 140, 24); 
    UILabel *oppLabel = [[UILabel alloc] initWithFrame:oppFrame]; 
    oppLabel.font = [UIFont boldSystemFontOfSize:14]; 
    oppLabel.text = [NSString stringWithFormat:@"%@", game.opponents.name]; 
    oppLabel.textAlignment = NSTextAlignmentCenter; 
    oppLabel.tag = 401; 
    [cell.contentView addSubview:oppLabel]; 

    CGRect dateFrame = CGRectMake(10, 40, 300, 12); 
    UILabel *dateLabel = [[UILabel alloc] initWithFrame:dateFrame]; 
    dateLabel.font = [UIFont systemFontOfSize:10]; 
    dateLabel.text = [NSString stringWithFormat:@"%@ - %@" , [dateFormatter stringFromDate: game.date] , game.location]; 
    dateLabel.textAlignment = NSTextAlignmentCenter; 
    dateLabel.tag = 501; 
    [cell.contentView addSubview:dateLabel]; 

} 

나는 데이터 변경 저장 대리자 방법을 사용하고 있습니다 :

-(void)EditGameViewControllerDidSave { 

    NSError *error = nil; 
    NSManagedObjectContext *context = self.managedObjectContext; 
    if (![context save:&error]) { 
     NSLog(@"Error! %@", error); 
    } 

    [self.navigationController popViewControllerAnimated:YES]; 

    [self.tableView reloadData]; 
} 

FetchedResultsController 변경 :

-(void) controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView beginUpdates]; 
} 

-(void) controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
} 

-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 

    UITableView *tableView = self.tableView; 

    switch (type) { 
     case NSFetchedResultsChangeInsert: 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      break; 

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 

} 

내 tableviewcontroller.m는 셀에 대한 다음과 같은 코드가 있습니다

답변

2

상용구 configureCell 메서드를 잘못 사용하고있는 것이 문제입니다.

애플의 템플릿 코드를 보면 이 완전히 만들어진 셀을 구성하는 데 사용된다는 것을 알 수 있습니다. 즉, 데이터로 채 웁니다.

스토리 보드 사용시 셀 생성이 크게 생략 될 수 있습니다. 스토리 보드에서는 일반적으로 if (cell==nil) {...}에 물건을 만들 필요가 없습니다. 물론 코드에서 if 블록을 사용하지 않고 별도의 메소드로 처리 할 수도 있습니다. 이 방법을 createCell이라고 부르는 것이 좋습니다 (configureCell이 아님).

configureCell:에서 데이터를 입력 할 수 있습니다. 이미 cellForRowAtIndexPath:의 if 블록 외부에서 수행하고있는 작업은 실제로 configureCell에 들어가는 작업입니다.

지금하고있는 방식대로 데이터가 변경되면 NSFetchedResultsControllerDelegate 콜백에 새 레이블을 만듭니다. NSFetchedResultsChangeUpdate (실제로 속성 변경시 발생하는 현상)의 경우 configureCell을 호출하지만 configureCell은 새보기를 만들어 셀에 추가합니다.

따라서 간단하게 셀 생성 코드를 configureCell 밖으로 이동하고 코드가 데이터로 셀을 채우는 코드를 configureCell으로 옮기면됩니다.

관련 문제