【问题标题】:Open edit view controller from table view using core data使用核心数据从表视图打开编辑视图控制器
【发布时间】:2013-12-29 19:54:00
【问题描述】:

在我的 iOS 应用程序中,我使用 Core Data 在表格视图中显示数据。在同一个视图中,我添加了一个添加按钮,它会打开一个新的视图控制器,我可以在其中添加新记录。

从这个视图我返回到表视图,新添加的记录正确显示。现在,我要做的是在表格视图上选择一行并打开一个新的视图控制器来编辑记录的字段。编辑视图控制器名称为EditViewController。这是我的表格视图控制器源代码,所以你可以解释一下将选定的行记录传递给编辑视图控制器的方法,以便我以后编辑和保存信息。 我已经看到了一些关于 didSelectedRowAtIndexPath 方法的问题示例,但所有示例都基于我的项目中没有使用的故事板。

#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 的回答之后,我已经完成了以下操作: 我在接口块的 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”,我不明白错误.... 谢谢

【问题讨论】:

  • 最后一个 sn-p 的第三行不正确。应该是detailViewController.selectedObject
  • 你是对的......再次感谢你,我希望这能解决我今天的问题。

标签: ios uitableview core-data uiviewcontroller


【解决方案1】:

第一步

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

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

第 2 步

检索正确的项目。

NSManagedObject *mo = [yourResultsController objectAtIndexPath:indexPath];

第 3 步

呈现一个模态控制器,向它传递数据。另一种方法是将您正在使用的控制器包装在 UINavigationController 中并推送新控制器。例子。

 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 支持的情况下编写的。

【讨论】:

  • 谢谢@flexaddicted,让我看看你的建议,如果需要进一步解释,我会告诉你。
  • 谢谢@flexaddicted,我已经实现了你的代码,更新了真实身份: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSManagedObject *mo = [fetchedResultsController objectAtIndexPath :indexPath]; EditToDoViewController *ac = [[EditToDoViewController alloc] init]; ac.setMo = mo; // 作为属性或传递给 YourAdditionalController [self presentViewController:ac animated:YES completion: nil] 的自定义 init 方法; }...但现在我需要如何在我的 EditVC 文件中接收 ac.setMo = mo 行发送的数据
  • 能否编辑您的问题并在此处添加详细信息?谢谢
  • 谢谢@flexaddicted,我已经按照您的指示更新了我的问题...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多