CoreData + UIViewController + UITableView

Posted

技术标签:

【中文标题】CoreData + UIViewController + UITableView【英文标题】: 【发布时间】:2016-03-20 19:05:04 【问题描述】:

我想最详细地解释我所面临的问题。 以前我直接使用 UITableViewController 而不是 UIViewController,问题是现在我需要在视图中显示更多内容,而不仅仅是 tableview,所以我创建了一个新视图。现在我有一个 UIViewController 具有: UIScrollView。里面有: 1. UIView + 1 UITableView

我正在使用自动布局。并且工作正常。我面临的问题是,自从我切换到使用此视图后,我无法使用 coredata 在表中显示内容。我能够在没有 coredata 的情况下做到这一点,但不能使用它。 在 interfacebuilder 中,我设置数据源并委托给这个 UIViewController。

标题:

#import <UIKit/UIKit.h>

@interface ResultsExtraVC : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property(nonatomic, strong) AGTCoreDataStack *model;
@property (strong, nonatomic) IBOutlet UILabel *labelRaceTime;
@property (strong, nonatomic) IBOutlet UILabel *labelTrackCondition;
@property (strong, nonatomic) IBOutlet UILabel *labelRaceStarttime;
@property (strong, nonatomic) IBOutlet UILabel *labelRaceMode;
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) IBOutlet UIView *raceInfoView;
@property(nonatomic, strong)NSNumber *eventID;
@property(nonatomic, strong)NSNumber *sectionID;
@property(nonatomic, strong)NSNumber *elementID;
@property(nonatomic, strong)NSNumber *categoryID;
@end

实施:

#import "ResultsExtraVC.h"
#import "ResultsExtraCellVC.h"
#import "Result.h"
#import "Element.h"
#import "Section.h"
#import <CoreData/CoreData.h>

@interface ResultsExtraVC () <NSFetchedResultsControllerDelegate>
//Core data
@property (nonatomic,strong) NSManagedObjectContext* managedObjectContext;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@end
static NSString * const cellIdentifier = @"resultsExrtaAltCell";


@implementation ResultsExtraVC
@synthesize managedObjectContext;
@synthesize fetchedResultsController = _fetchedResultsController;
@synthesize eventID, sectionID, elementID, categoryID, model;

- (void)viewDidLoad 
    [super viewDidLoad];
    managedObjectContext = self.model.context;

    [self getResults];

    NSLog(@"ElementName: %@", [self getElementName]);
    NSLog(@"SectionName: %@", [self getSectionName]);
    [self configureHeatInfo];
    // Do any additional setup after loading the view.

- (void)viewDidUnload

    [super viewDidUnload];

    self.fetchedResultsController = nil;


- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

#pragma mark - View Configuration
-(void) configureHeatInfo
    _scrollView.backgroundColor = [UIColor cyanColor];
    _scrollView.translatesAutoresizingMaskIntoConstraints = NO;

    _labelRaceTime.translatesAutoresizingMaskIntoConstraints = NO;
    _labelRaceTime.text = @"Race time:\n10:00";

    _labelRaceMode.translatesAutoresizingMaskIntoConstraints = NO;
    _labelRaceMode.text = @"Mode: Groupstart";

    _labelTrackCondition.translatesAutoresizingMaskIntoConstraints = NO;
    _labelTrackCondition.text = @"Track Condition: Dry";

    _labelRaceStarttime.translatesAutoresizingMaskIntoConstraints = NO;
    _labelRaceStarttime.text = @"Starttime: 12.03.2016 11:09:10";

    //self.tableView.translatesAutoresizingMaskIntoConstraints = NO;
    /*self.tableView.dataSource = self;
      self.tableView.delegate = self;*/


#pragma mark - Table view data source

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


/*- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return 20;
*/
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    id  sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
    #ifndef NDEBUG
        NSLog(@"%s (line:%d) - Rows: %lu",__PRETTY_FUNCTION__,__LINE__, (unsigned long)[sectionInfo numberOfObjects]);
    #endif
    // Return the number of rows in the section.

    return [sectionInfo numberOfObjects];


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    return [self basicCellAtIndexPath:indexPath];

- (ResultsExtraCellVC *)basicCellAtIndexPath:(NSIndexPath *)indexPath 
    ResultsExtraCellVC *cell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    // Using a cell identifier will allow your app to reuse cells as they come and go from the screen.
    if (cell == nil) 
        #ifndef NDEBUG
            NSLog(@"%s (line:%d)",__PRETTY_FUNCTION__,__LINE__);
        #endif
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ResultsExtraCell" owner:self options:nil];
        cell = (ResultsExtraCellVC *)[nib objectAtIndex:0];
    
    [self configureCell:cell atIndexPath:indexPath];

    return cell;


- (void)configureCell:(ResultsExtraCellVC *)cell atIndexPath:(NSIndexPath *)indexPath 
    #ifndef NDEBUG
        NSLog(@"%s (line:%d)",__PRETTY_FUNCTION__,__LINE__);
    #endif

    Result *result = [_fetchedResultsController objectAtIndexPath:indexPath];

    [cell.cellRankNr setText:[NSString stringWithFormat:@"%@",[result endposition]]];
    [cell.cellName setText:[NSString stringWithFormat:@"%@ %@ (%@)",[result pilotprename], [result pilotname], [result carnumber]]];
    [cell.cellResult setText:[NSString stringWithFormat:@"%@",NSLocalizedFormatString(@"LapsXnTimeX",[result rlaps],[result rendtime])]];
    [cell.cellRace setText:[NSString stringWithFormat:@"%@",NSLocalizedFormatString(@"BestTimeXnAvgTimeX",[result rbesttime], [result rmediumtime])]];



-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath


    if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
    
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    

    if ([tableView respondsToSelector:@selector(setLayoutMargins:)])
    
        [tableView setLayoutMargins:UIEdgeInsetsZero];
    

    if ([cell respondsToSelector:@selector(setLayoutMargins:)])
    
        [cell setLayoutMargins:UIEdgeInsetsZero];
    




-(NSString *)getElementName
    NSString *elementName = @"";

    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Elements" inManagedObjectContext:managedObjectContext];
    NSFetchRequest *request = [[NSFetchRequest alloc] init] ;
    [request setEntity:entityDescription];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eventid = %@ AND sectionid = %@ AND elementid = %@ AND categoryid= %@)",eventID, sectionID, elementID, categoryID];
    [request setPredicate:predicate]; //added this line later
    NSArray *array = [managedObjectContext executeFetchRequest:request error:nil];
    if([array count]> 0)
        Element *element = [array lastObject];
        elementName = [element name];
    
    return elementName;


-(NSString *)getSectionName
    NSString *sectiontName = @"";

    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Sections" inManagedObjectContext:managedObjectContext];


    NSFetchRequest *request = [[NSFetchRequest alloc] init] ;
    [request setEntity:entityDescription];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eventid = %@ AND sectionid = %@)",eventID, sectionID];
    [request setPredicate:predicate]; //added this line later
    NSArray *array = [managedObjectContext executeFetchRequest:request error:nil];
    if([array count]> 0)
        Section *section = [array lastObject];
        sectiontName = [section name];
    
    return sectiontName;


-(void)getResults
    // Initialize Fetch Request
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Results"];

    // Add Sort Descriptors
    //[fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"endposition" ascending:YES]]];

    //Predicate
    NSPredicate *commentsPredicate = [NSPredicate predicateWithFormat:@"(eventid = %@ AND sectionid = %@ AND elementid = %@)",eventID, sectionID, elementID];
    [fetchRequest setPredicate:commentsPredicate]; //added this line later

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"endposition"
                                                                   ascending:YES];
    NSArray *sortDescriptors = @[sortDescriptor];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Initialize Fetched Results Controller
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

    // Configure Fetched Results Controller
    [self.fetchedResultsController setDelegate:self];

    // Perform Fetch
    NSError *error = nil;
    [self.fetchedResultsController performFetch:&error];

    if (error) 
        NSLog(@"Unable to perform fetch.");
        NSLog(@"%@, %@", error, error.localizedDescription);
    

#pragma mark -
#pragma mark Fetched Results Controller Delegate Methods
- (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 
    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 configureCell:(ResultsExtraCellVC *)[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
        
        case NSFetchedResultsChangeMove: 
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
        
    

@end

我的视图如下所示:

我尝试遵循一些教程,因为这是我第一次使用 CoreData 执行此操作,以前我总是只使用 UITableViewController。 我跟着这个:http://code.tutsplus.com/tutorials/core-data-from-scratch-more-nsfetchedresultscontroller--cms-21777 并且还检查了:CoreData TableView inside UIViewController

但没有成功。 如果有人能帮我解决这个问题,我会很棒。

提前致谢

【问题讨论】:

您实际上从numberOfSectionsInTableViewnumberOfRowsInSection 返回了什么值? 嗨菲利普,它返回 0,这就是为什么不显示行的原因,问题是结果实体有内容和 viewDidLoad 中的其他查询: NSLog(@"ElementName: %@ ", [self getElementName]); NSLog(@"SectionName: %@", [self getSectionName]);返回内容,因此模型和上下文设置得很好。 【参考方案1】:

可能在代码行中

// Initialize Fetched Results Controller
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

sectionNameKeyPath 不见了?它必须是 NSSortDescriptor 键之一。

【讨论】:

以上是关于CoreData + UIViewController + UITableView的主要内容,如果未能解决你的问题,请参考以下文章

未调用 DidEndSendingToApplication

CoreData(iOS):是不是需要创建数据库才能使用CoreData?coredata可以对简单的平面文件进行操作吗? [关闭]

CoreData 本地数据存储

CoreData与CloudKit同步时将图像保存到CoreData?

RestKit + CoreData:从CoreData缓存中排除某些对象

在 UITableview 中显示图像