【问题标题】:Passing a Selected Object to a New View Controller via Push通过 Push 将选定对象传递给新的视图控制器
【发布时间】:2013-12-20 07:07:51
【问题描述】:

所以我下载了以下项目来教自己更多关于通过视图等传递对象的知识,但我遇到了一个小问题: https://github.com/rlgoldberg2/MyStore

我的视图控制器

  • DeviceViewController - 主视图,从 tableview 行添加或编辑对象的选项
  • DeviceDetailViewController - 编辑或创建对象的地方

在 Storyboard 上,我将两个视图控制器之间的转换类型从 Model 更改为 Push(以启用导航控制器附带的光荣 UINavigationBar)。向 UITableView 添加新对象可以正常工作,但是当我从主视图中选择要编辑的对象(从 UITableView 中)时,该对象在详细视图中打开为空白 - 这意味着文本字段为空白。我相信我需要在DeviceViewController的以下小代码sn-p中编辑一些代码以使其与Push转换兼容?

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
 if ([[segue identifier] isEqualToString:@"UpdateDevice"]) {
     NSManagedObject *selectedDevice = [self.devices objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
     DeviceDetailViewController *destViewController = segue.destinationViewController;
     destViewController.device = selectedDevice;
 }

那么我该如何解决这个问题呢?有什么想法吗?


如果我错了——我很可能是错的,而且你觉得没有必要自己下载项目,这里是 DeviceViewController.m 的全部内容:

//
//  DeviceViewController.m
//  MyStore
//
//  Created by Richard Goldberg on 10/11/13.
//  Copyright (c) 2013 Richard Goldberg. All rights reserved.
//

#import "DeviceViewController.h"

@interface DeviceViewController ()

@property (strong) NSMutableArray *devices;

@end

@implementation DeviceViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

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

- (NSManagedObjectContext *)managedObjectContext
{
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    if ([delegate performSelector:@selector(managedObjectContext)]) {
        context = [delegate managedObjectContext];
    }
    return context;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Fetch the devices from persistent data store
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Device"];
    self.devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

    [self.tableView reloadData];
}

#pragma mark - Table view data source


- (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.devices.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    NSManagedObject *device = [self.devices objectAtIndex:indexPath.row];
    [cell.textLabel setText:[NSString stringWithFormat:@"%@ %@", [device valueForKey:@"name"], [device valueForKey:@"version"]]];
    [cell.detailTextLabel setText:[device valueForKey:@"company"]];

    return cell;
}


// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}



// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle) editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSManagedObjectContext *context = [self managedObjectContext];

    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete object from database
        [context deleteObject:[self.devices objectAtIndex:indexPath.row]];

        NSError *error = nil;
        if (![context save:&error]) {
            NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]);
            return;
        }

        // Remove device from table view
        [self.devices removeObjectAtIndex:indexPath.row];
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}


/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/


#pragma mark - Navigation

// In a story board-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
 if ([[segue identifier] isEqualToString:@"UpdateDevice"]) {
     NSManagedObject *selectedDevice = [self.devices objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
     DeviceDetailViewController *destViewController = segue.destinationViewController;
     destViewController.device = selectedDevice;
 }

}



@end

【问题讨论】:

  • 从模式更改为推送应该会使细节控制器无法正常工作。我下载了那个项目,将“更新设备”segue 改为推送,效果很好。
  • @rdelmar 我该怎么做呢?每次我尝试这样做时,都会遇到很多错误。
  • 点击 segue 并在属性检查器中将 Modal 更改为 Push。
  • @rdelmar 我已经这样做了,但是由于某种原因,单击现有对象时它仍然显示为空白:Screenshot.png
  • 如果没有看到您的项目,我无法判断您做了什么。如果你想把它发给我或张贴在某个地方,我会看的。

标签: ios iphone objective-c uinavigationcontroller pushviewcontroller


【解决方案1】:

除非您的视图控制器由导航控制器管理,否则您不能使用推送转场。您应该能够在情节提要中选择根场景并选择嵌入导航控制器以使您的应用由导航控制器管理。

一旦你这样做了,你的 push segue 应该可以工作,就像你的模态 segues 一样。

在您发布的代码中,您的 DeviceViewController 类有一个设备属性(设备对象数组,无论它们是什么。)

您的 PrepareForSegue 方法正在尝试在目标视图控制器中设置设备(单数)属性,而不是设备。

【讨论】:

【解决方案2】:

问题是,当您从模式切换到推送时,您删除并重新建立了连接,并且从未输入新转场的标识符。这导致 prepareForSegue 中的 if 子句评估为 false,因此 selectedDevice 从未传递给细节控制器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    相关资源
    最近更新 更多