【问题标题】:iOS UITableView sections with fetchedResultsController confusioniOS UITableView 部分与 fetchedResultsController 混淆
【发布时间】:2013-08-24 01:47:08
【问题描述】:

我有一个实体在一个部分的表格视图中显示。该实体有两个属性,workoutNametrainingLevel。两者都是字符串类型。培训级别由 3 种类型组成:1、2、3。(trainingLevel =(整数 16 或字符串类型?哪个更理想?)我想将表格分成三个部分,每个部分包含相应培训级别的条目.

我该怎么做?我目前使用的代码如下:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return self.workoutType.workouts.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell =
    [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                  reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }


    WorkoutSet *workoutSet = [self.fetchedResultsController objectAtIndexPath:indexPath];


    cell.textLabel.text = workoutSet.workoutName;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"(%d)", workoutSet.days.count];    
}

-(void)fetchWorkoutSets
{

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"WorkoutSet"];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"workoutType = %@", self.workoutType];

    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"workoutName" ascending:YES];
    [fetchRequest setSortDescriptors:@[sortDescriptor]];
    [fetchRequest setPredicate:predicate];
    self.fetchedResultsController = [[NSFetchedResultsController alloc]
                                 initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext
                                 sectionNameKeyPath:nil cacheName:nil];

    NSError *error;
    if (![self.fetchedResultsController performFetch:&error])
    {
        NSLog(@"Fetch failed: %@", error);
    }
}

我正在努力解决的是:

  • 如何通过核心数据模型通过获取训练级别为 1 或 2 或 3 的条目数来确定每个部分的行数。
  • 如何通过获取正确的项目来填充每个部分的行。
  • 如何为每个部分标题指定标题。

【问题讨论】:

  • 你已经差不多了。只需检查NSFetchedResultsController 的文档,特别是指定初始化程序的sectionNameKeyPath 参数,您希望将其设置为trainingLevel 属性。
  • 另请注意,您的 fetchedResultsController getter 应该执行获取,而不是 fetchWorkoutSet,否则如果您需要确保已获取锻炼集并且您需要 fetchedResults,您将有两个不同的调用.

标签: ios core-data tableview nsfetchedresultscontroller


【解决方案1】:

这里有一个很好的使用fetchedResultsControllers的教程:http://www.raywenderlich.com/999/core-data-tutorial-for-ios-how-to-use-nsfetchedresultscontroller

创建一些属性来保存您的上下文并获取:

@property (nonatomic,strong)NSManagedObjectContext* managedObjectContext;
@property (nonatomic,retain)NSFetchedResultsController *fetchedResultsController;

在您的fetchedResultsController 属性中,使用sectionKeyNamePath 将您获取的结果设置为分段:

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController != nil) {
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
                                           entityForName:@"Workouts"
                                  inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
        initWithKey:@"workoutName" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController =
        [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:managedObjectContext 
              sectionNameKeyPath:@"trainingLevel"
                       cacheName:@"Root"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

}

您的fetchedResultsController 的初始填充可以发生在您的-viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }
}

然后,您将返回部分中的部分数和行数,如下所示:

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

- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section
{
   id <NSFetchedResultsSectionInfo> sectionInfo = 
       [[[self fetchedResultsController] sections] objectAtIndex:section];

   return [sectionInfo numberOfObjects];        
}

然后您可以像这样获取特定行的托管对象:

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

   // init the cell
   // and whatever other setup needed

   WorkoutSet *workoutSet = 
      [self.fetchedResultsController objectAtIndexPath:indexPath];

   // configure the cell from the managedObject properties
}

【讨论】:

  • 我已经尝试了上述方法,但没有成功,主要是在你说要使用 NSManagedObject 的最后遇到麻烦......不知道如何通过它获取我的数据......谢谢
  • @user2512523 更新了附加代码以使其更清晰。您的 WorkoutSet 对象是 fetchedResultsController 返回的对象。
  • @user2512523 如果此答案对您有所帮助,请将其标记为已接受,这样问题就不会显示为仍处于打开状态。
猜你喜欢
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多