2014-06-24 4 views
0

레이아웃을 개선하기 위해 내 애플 리케이션에서 만든보기를 다시 작성하고 싶습니다. 원래 CoreData를 소스로 사용하는 TableViewController를 구현했습니다. 이 뷰는 TableViewController에 뷰를 추가해야만 테이블이 무의미하게 동작하고 더 많은 행이 추가 될 때 화면 밖으로 스크롤되지 않을 때까지 잘 작동했습니다. 초기 implemetnation는 NSFetchedResultsController에 사과 안내에 따라 다음과 같습니다CoreData TableView 내 UIViewController

CoreDataTableViewController.h :

@interface CoreDataTableViewController : UITableViewController <NSFetchedResultsControllerDelegate> 
    @property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController; 
    - (void)performFetch; 
    @property (nonatomic) BOOL suspendAutomaticTrackingOfChangesInManagedObjectContext; 
    @property BOOL debug; 
@end  

CoreDataTableViewController.m : 내 TableViewController에서

@interface CoreDataTableViewController() 
    @property (nonatomic) BOOL beganUpdates; 
@end 

@implementation CoreDataTableViewController 

#pragma mark - Properties 

@synthesize fetchedResultsController = _fetchedResultsController; 
@synthesize suspendAutomaticTrackingOfChangesInManagedObjectContext = _suspendAutomaticTrackingOfChangesInManagedObjectContext; 
@synthesize debug = _debug; 
@synthesize beganUpdates = _beganUpdates; 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return YES; 
} 

#pragma mark - Fetching 

- (void)performFetch 
{ 
<snipped> 
} 

- (void)setFetchedResultsController:(NSFetchedResultsController *)newfrc 
{ 
<snipped> 
} 

#pragma mark - UITableViewDataSource 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return [[self.fetchedResultsController sections] count]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 

    return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects]; 
} 

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{ 

return [[[self.fetchedResultsController sections] objectAtIndex:section] name]; 
} 

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index 
{ 
return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index]; 
} 

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 
{ 

    return [self.fetchedResultsController sectionIndexTitles]; 
} 

#pragma mark - NSFetchedResultsControllerDelegate 
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
{ 
<..snipped..> 
} 

- (void)controller:(NSFetchedResultsController *)controller 
    didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 
      atIndex:(NSUInteger)sectionIndex 
forChangeType:(NSFetchedResultsChangeType)type 
{ 
<...snipped...> 
} 


- (void)controller:(NSFetchedResultsController *)controller 
    didChangeObject:(id)anObject 
    atIndexPath:(NSIndexPath *)indexPath 
forChangeType:(NSFetchedResultsChangeType)type 
    newIndexPath:(NSIndexPath *)newIndexPath 
{ 
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext) 
    { 
     switch(type) 
     { 
      case NSFetchedResultsChangeInsert: 
       [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       break; 

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

      case NSFetchedResultsChangeUpdate: 
       [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
       break; 

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

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller 
{ 
} 

- (void)endSuspensionOfUpdatesDueToContextChanges 
{ 
} 

- (void)setSuspendAutomaticTrackingOfChangesInManagedObjectContext:(BOOL)suspend 
{ 
} 

@end 

, CDTVC.h라고, I CoreDataTableViewController에서 을 상속받은 하위 클래스를 만들었습니다.

@interface CDTVC : CoreDataTableViewController 
    @property (nonatomic, copy) NSString *status; 
    @property (nonatomic, copy) NSString *totalTally; 
    @property (nonatomic, retain) IBOutlet UILabel *tallyDisplayLabel; 
@end 
내 CDTVC.m에서

:

#pragma mark - CoreDataViewController 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"entryCRVPCell"]; 

    if (cell == nil) { 
     UITableViewCellStyle cellStyle = UITableViewCellStyleSubtitle; 
     cell = [[UITableViewCell alloc] initWithStyle:cellStyle reuseIdentifier:@"entryCRVPCell"]; 
    } 

    TallyEntry *tallyEntry = [self.fetchedResultsController objectAtIndexPath:indexPath]; 

    if (tallyEntry) { 
     NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
     [dateFormatter setDateFormat:@"MMM dd, yyyy"]; 

     NSString *stringDate = [dateFormatter stringFromDate:tallyEntry.dateCreated]; 
     cell.textLabel.numberOfLines = 0; 
     cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@\n%@", tallyEntry.category, tallyEntry.name, stringDate]; 
    } 

    return cell; 
} 

은 이제 내보기 컨트롤러가 더 이상 : 그것이 부모에 의해 처리되지 않는 가이드 라인 당

// Gets called when the managedObjectContext is ready 
-(void) loadTally 
{ 
    if (managedObjectContext) { 
     NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Entry"];   
     request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"dateCreated" ascending:NO]]; 
     request.predicate = nil;    

     self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 
    } else { 
     self.fetchedResultsController = nil; 
    } 

    [self performFetch]; // <<----This refreshes the tableview controller 
} 

, 나는 자신이 구현 할 필요가 없습니다 TableViewController가 있지만 TableView가 포함 된 ViewController는 다음과 같습니다.

enter image description here

그래서 새로운 View Controller를 소개했는데 이것이 내가 한 일이 해킹이고 솔루션만큼 우아하지는 않습니다.

CDTVC.h에서 다음과 같이 추가했습니다. TallyViewController에 액세스 데이터 :

@synthesize dataSource = _dataSource; 

내가 TallyViewController에 loadTally 구현 이동 :

@protocol TallyViewDataSource 
    -(void)setupTallyLabel:(float) tally; 
    -(NSString *) getTallyMode; 
@end 

@property (nonatomic, retain) IBOutlet id <TallyViewDataSource> dataSource; 

는 CDTVC.m에서, I는 다음의 첨가.

TallyViewController.h가 지금은 더 이상 CoreDataViewController에서 상속 할 수 없습니다 의미의 UIViewController에서 상속합니다 : 그래서

@interface TallyViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, 
TallyViewDataSource> { 
    IBOutlet UITableView* myTableView; 
} 

@property (nonatomic, retain) IBOutlet UILabel *tallyDisplayLabel; 
@property (nonatomic, retain) IBOutlet UITableView *myTableView; 
@property (nonatomic, retain) CDTVC* CDTVCTable; 

이 다중 상속의 문제를 해결하기 위해, 나는 CDTVCTable 내 자신의 인스턴스를 할당하기로 결정 내 TallyViewController.m에서 :

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    _CDTVCTable = [[CDTVC alloc] init]; 
    _CDTVCTable.dataSource = self; 
} 

-(void) loadTally 
{ 
    if (managedObjectContext) { 
     NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Entry"];   
     request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"dateCreated" ascending:NO]]; 
     request.predicate = nil;    

     _CDTVCTable.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 
    } else { 
     _CDTVCTable.fetchedResultsController = nil; 
    } 

    [_CDTVCTable performFetch]; 
    [self.myTableView reload]; //<----Had to add this to refresh the local table. 
} 

는 또한 승, 테이블 뷰 위임을 모두 구현하지만 내 CDTVCTable을 로 리디렉션했다 이전과 나는 여기 만있는 tableView를 구현했다 : cellForRowAtIndexPath :

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return [_CDTVCTable numberOfSectionsInTableView:tableView]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [_CDTVCTable tableView:tableView numberOfRowsInSection:section]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    return [_CDTVCTable tableView:tableView cellForRowAtIndexPath:indexPath]; 
} 

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    return [_CDTVCTable tableView:tableView commitEditingStyle:editingStyle forRowAtIndexPath:indexPath]; 
} 

그래서 질문은, 대표 및 데이터 소스와이를 구현하는 더 우아한 방법이있다.나는 델리게이트에 대한 나의 이해를 받아 들여야하고 데이터 소스가 약해서 더 좋은 방법으로 이것을 설명 할 수는 없다.

+0

소화 할 부분이 많습니다. 질문을 더 간결하게 말할 수 있다면 괜찮은 답변을 얻을 수있는 더 좋은 기회를 갖게 될 것입니다. – Caleb

+0

한 줄의 답을 피하기 위해 완벽한 그림을 보여주고 싶었습니다. 대표자를 사용하십시오. 여기서 그 방법을 취하는 방법이 명확하지 않습니다. –

답변

0

정적 뷰 요소를 UITableview와 섞어 야 할 경우에는 일반적으로 ViewController에 컨테이너 뷰를 추가하고 외부 UITableview를 연결하는 것이 가장 쉽다는 것을 알게되었습니다.

Segue를 통해 정적 ViewController에서 전달 데이터를 UITableView로 보내고 대리자를 사용하여 정적 ViewController가 UITableview에서 발생한 상황을 알 수 있도록합니다.

+0

고마워,하지만 그건 내가하는 일과 크게 다르지 않다. 내 문제는 내가 UITableView 대신 UITableViewController 핵심 데이터 동작을 사용하여 다른 및 그 내가 원활하게 통합하는 고군분투입니다. –

+1

오 ~ 알겠습니다. 죄송합니다. –

+0

아이디어를 가져 주셔서 감사합니다, 나는 컨테이너의 개념이 미래에 매우 유용 할 수 있다고 생각합니다! –

관련 문제