ios - 使用核心数据从 TableView 打开编辑 View Controller

标签 ios uitableview core-data uiviewcontroller

在我的 iOS 应用程序中,我使用 Core Data 在表格 View 上显示数据。在同一 View 上,我添加了一个添加按钮,该按钮打开一个新的 View Controller ,我可以在其中添加新记录。

从此 View 返回 TableView ,新添加的记录正确显示。现在,我想做的是在 TableView 上选择一行并打开一个新的 View Controller 来编辑记录的字段。编辑 View Controller 名称是EditViewController。这是我的 TableView Controller 源代码,所以您可以向我解释将所选行记录传递给编辑 View Controller 的实现方法,以便我以后可以编辑和保存信息。 我已经看到有关 didSelectedRowAtIndexPath 方法的问题的一些示例,但所有示例都基于 Storyboard,我没有在我的项目中使用它。

#import "RootViewController.h"
#import "AddToDoViewController.h"


@interface RootViewController ()
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
@end


@implementation RootViewController

@synthesize fetchedResultsController, managedObjectContext,AddToDoButton;


#pragma mark -
#pragma mark View lifecycle

- (void)viewDidLoad {
  [super viewDidLoad];
  [self setTitle:@"Today"];
  [[self navigationItem] setRightBarButtonItem:[self editButtonItem]];





  NSError *error = nil;
  if (![[self fetchedResultsController] performFetch:&error])
  {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
  }
}
- (void) viewWillAppear:(BOOL)animated{
    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error])
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    [self.tableView reloadData];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
  NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
  [[cell textLabel] setText:[[managedObject valueForKey:@"thingName"] description]];
  [[cell detailTextLabel] setText:[[managedObject valueForKey:@"thingDescription"] description]];
  [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    cell.textLabel.textColor = [UIColor blueColor];
    cell.textLabel.font = [UIFont fontWithName:@"Noteworthy" size:16.0f];
    cell.detailTextLabel.font = [UIFont fontWithName:@"Noteworthy" size:14.0f];
}

#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
  return [[fetchedResultsController sections] count];
}

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

- (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:@"Cell"] autorelease];
  }

  [self configureCell:cell atIndexPath:indexPath];

  return cell;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
  if (editingStyle == UITableViewCellEditingStyleDelete)
  {
    NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
    [context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

    NSError *error = nil;
    if (![context save:&error])
    {
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
      abort();
    }
  }   
}

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
  return YES;
}

- (void)tableView:(UITableView *)tableView 
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath 
      toIndexPath:(NSIndexPath *)destinationIndexPath;
{  
  NSMutableArray *things = [[fetchedResultsController fetchedObjects] mutableCopy];

  // Grab the item we're moving.
  NSManagedObject *thing = [[self fetchedResultsController] objectAtIndexPath:sourceIndexPath];

  // Remove the object we're moving from the array.
  [things removeObject:thing];
  // Now re-insert it at the destination.
  [things insertObject:thing atIndex:[destinationIndexPath row]];

  // All of the objects are now in their correct order. Update each
  // object's displayOrder field by iterating through the array.
  int i = 0;
  for (NSManagedObject *mo in things)
  {
    [mo setValue:[NSNumber numberWithInt:i++] forKey:@"displayOrder"];
  }

  [things release], things = nil;

  [managedObjectContext save:nil];
}






#pragma mark -
#pragma mark Fetched results controller
- (IBAction)AddToDoAction:(id)sender {

    AddToDoViewController *viewController = [[AddToDoViewController alloc] init];
    [self presentViewController:viewController animated:YES completion:nil];

}

- (NSFetchedResultsController *)fetchedResultsController
{
  if (fetchedResultsController) return fetchedResultsController;

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

  [fetchRequest setEntity:entity];

  NSSortDescriptor *sortDescriptor = 
              [[NSSortDescriptor alloc] initWithKey:@"displayOrder" 
                                          ascending:YES];

  NSArray *sortDescriptors = [[NSArray alloc] 
                              initWithObjects:sortDescriptor, nil];  
  [fetchRequest setSortDescriptors:sortDescriptors];

  NSFetchedResultsController *aFetchedResultsController = 
              [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                                  managedObjectContext:managedObjectContext
                                                    sectionNameKeyPath:nil cacheName:@"ThingsCache"];
  aFetchedResultsController.delegate = self;
  [self setFetchedResultsController:aFetchedResultsController];

  [aFetchedResultsController release];
  [fetchRequest release];
  [sortDescriptor release];
  [sortDescriptors release];

  return fetchedResultsController;
}    

- (void)dealloc {
  [fetchedResultsController release];
  [managedObjectContext release];


  [super dealloc];
}


@end

又嗨了。在 @flexaddicted 的回答之后我做了以下工作: 我已将以下代码添加到界面 block 的 EditToDoViewController.h 文件中:

NSManagedObject *selectedObject;

还有以下声明:

@property (nonatomic, retain) NSManagedObject *selectedObject;

在我的 EditToDoViewController.m 文件中,我添加了以下代码:

@synthesize selectedObject;

didSelectRowAtIndexPath 方法更改为:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


    EditToDoViewController *detailViewController = [[EditToDoViewController alloc] initWithNibName:@"EditToDoViewController" bundle:nil];
    NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
    EditToDoViewController.selectedObject = selectedObject;

}

但此时我收到此错误消息: 在“EditToDoViewController”类型的对象上找不到属性“selectedObject”

我认为我已经很好地声明了属性“selectedObject”,我不明白这个错误...... 谢谢

最佳答案

第一步

UITableView 实现正确的委托(delegate)方法,即 UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // do something here (see Step 2 and 3)
}

第 2 步

检索正确的项目。

NSManagedObject *mo = [yourResultsController objectAtIndexPath:indexPath];

步骤 3

呈现一个模态 Controller ,向其传递数据。另一种方法是将您正在使用的 Controller 包装在 UINavigationController 中,然后推送一个新 Controller 。例子。

 YourAdditionalViewController *ac = [[YourAdditionalViewController alloc] init];
 ac.setMo = mo; // as a property or passed to a custom init method of YourAdditionalController
 [self presentViewController:ac animated:YES completion: nil];

所以回顾一下。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSManagedObject *mo = [yourResultsController objectAtIndexPath:indexPath];

    YourAdditionalViewController *ac = [[YourAdditionalViewController alloc] init];
    ac.setMo = mo; // as a property or passed to a custom init method of YourAdditionalController
    [self presentViewController:ac animated:YES completion: nil];
}

如果我需要改进我的答案,请告诉我。

附言检查代码,因为我是在没有 Xcode 支持的情况下编写的。

关于ios - 使用核心数据从 TableView 打开编辑 View Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20525967/

相关文章:

ios - 在核心数据数据库中搜索特定半径的附近地点 [swift]

ios - 在 Xcode 8.1 中创建 NSManagedObject 类显示错误

ios - 如何以编程方式在 UITableViewController 的 NavigationBar 内设置 UISearchDisplayBar

iphone - iOS:如何判断 UILabel 的字体是否已自动调整大小?

ios - 保存 NSNumber 核心数据

ios - UITableViewCell 副标题不显示

ios - iOS7中的SpriteKit animateWithTextures不起作用

objective-c - 在 ViewController 中的两个 View 上以编程方式设置自动布局约束

ios - 删除具有多个TableView的行

xcode - SwiftUI:如何在预览中显示测试 CoreData 实例?