将单元格数组项传递给另一个视图控制器

时间:2015-04-28 12:29:32

标签: ios objective-c arrays uitableview object

所以这是我一直在阅读的一个常见问题,我仍在学习,请记住这一点。

基本上我的应用程序当前允许您将项目添加到tableview,然后当您从表格视图中选择一个单元格时,它会显示另一个视图控制器,用于显示该单元格的详细信息。

Diagram

在我的tableView实现文件.m中,我有代码在单击一个单元格时转到视图控制器:

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

    SelectedItemViewController *selectView = [[SelectedItemViewController alloc] initWithNibName:@"SelectedView" bundle:nil];

    [selectView.titleView setText:@"test"];

    [self performSegueWithIdentifier:@"showSelected" sender:indexPath];
}

“setText”代码片段只是测试我是否能够在ViewCellController中更改textLabel。

当用户保存新项目时,这是在返回TableView时调用的以下segue代码。 'toDoItem'是一个NSMutableArray。

 -(IBAction)unwindToList:(UIStoryboardSegue *)segue {
    AddToDoItemViewController* source = [segue sourceViewController];
    ToDoItem* item = source.toDoItem;
    if (item != nil){
        [self.toDoItems addObject:item];
        [self.tableView reloadData];
    }
}

显然我做错了。

我想要了解的是我的能力:

  1. 选择一个单元格,从数组中获取该索引的数据,而不仅仅是单元格数据,数据包括:标题,描述,DueDate和完成。

  2. 在另一个视图控制器中显示它。

  3. 操纵完成布尔值并保存,以便在再次单击时保持这种方式。

  4. 我不想要一个完整的答案只是指向正确的方向,所以我可以自己解决,谢谢!

2 个答案:

答案 0 :(得分:1)

根据我的理解,你处于一个简单的Tableview细节情况中。

您有一个项目列表,并且您希望在下一个视图中保留特定项目,以便您可以显示它的详细信息(或编辑或以某种方式进行交互)。

例如,我正在考虑联系人列表或食谱列表。你有一份餐点清单,你可以看到他们的头衔和评级,并说你想看到成分,你必须点击它。

如果我在这里错了,请纠正我,否则,这很简单。

您需要一个tableview(在UITableViewController或简单UIViewController中添加自己的tableview)。无论哪种方式,你的tableview显然已经完成,所以我可以跳过那一部分。该控制器应该在UINavigationController中,它应该是您唯一的导航控制器。我会直截了当地说,如果你是初学者(就像我一样),你可能会制作一段时间只有一个导航控制器的应用程序。

您还拥有一系列自定义对象,您肯定拥有这些对象。假设它是Contact,您有一组Contact个对象。

构建tableview时,可以使用该联系人数组并相应地创建单元格。

这是一个非常简短的例子:

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

    static NSString *identifier = @"ContactCell";

    //I'm assuming you're using a custom cell    
    ContactCell *cell     = [self.tableView dequeueReusableCellWithIdentifier:identifier];

    if (cell == nil) {
        cell = [[ContactCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }


    Contact *contact = [_dataArray objectAtIndex:indexPath.row];
    cell.nameLabel.text = contact.name;     
    cell.phoneNumberLabel.text = contact.phone;
    return cell;

}

这只是一个简短的例子来阐明我的观点;请注意,您必须设置数据源和委托以及其他方法(-numberOfRowsInSection:)才能使tableview正常工作。

很好,你有一个联系人列表和一个带有电话号码的小文本,但你想显示他们的地址或你已经在你的阵列中但尚未显示的任何内容。所有数据都已加载,你真的很想表现出来。一个很好的用途确实是挖掘细胞并推动另一种观点。推送是好的,因为您可以使用操作系统为您创建的后退按钮,这就是您需要UINavigationController

的原因

要处理这个问题,您需要两种方法,首先是tableview方法didSelectRowAtIndexPath,然后是prepareForSegue

有很多方法可以解决这个问题,但我会尝试做一些简单的事情。你想知道你拍了哪个项目,你想把它交给下一个视图。所以,好吧,要将它提供给下一个视图,您需要先拥有它。我们将:

  • 在数组中找到它
  • 保留某种引用(它的索引路径或整个项目)
  • 传递它

您可以使用ivar来保留该引用,有更好/不同的方式,但这很简单。其他人可能想用不同的风格做出自己的答案,或者在我的回答结束时用另一种方式编辑我的答案。

ivar只是.m文件顶部的一个实例变量,您可以访问该.m文件中的任何位置。它有点像@property,但只有那个类/控制器可以看到。

您可以在控制器的最顶层使用它,该行应该在viewDidLoad之前就已存在,只需添加花括号和变量。

@implementation MyTableViewController
{
    Contact *_myContactToPass;
}

以下方法只会找到该项并调用“传递”方法

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

    _myContactToPass = [_dataArray objectAtIndex:indexPath.row];
    [self performSegueWithIdentifier:@"fromTableViewToDetails" sender:self];
}

DetailsViewController中,您的.h文件中需要一个@property作为联系人对象,以及一些标签和按钮以及您需要的所有优质爵士乐。使用_contact属性填充所有这些标签,并且因为在加载该视图之前总是会传递它,所以它们将从选定的联系人加载动态数据,而不是从故事板加载静态标签。

- (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:@"fromTableViewToDetails"]){

        DetailsViewController *vc = (DetailsViewController*)segue.destinationViewController;
        vc.contact = _myContactToPass;  
}

注意:

  • 我假设您在故事板中创建了一个名为fromTableViewToDetails
  • 的推送segue
  • 我假设你知道如何做到这一点
  • 我很失望你找不到一个简单的tableview教程来自学,这对任何开发者来说都是非常重要的一步:搜索,阅读,尝试,重试,学习。 我已经尽可能详细地回答了问题,并会回答你的问题,但是一个简单的谷歌搜索会引导你进入你现在会记住的惊人网站:

    AppCoda.com

    RayWenderlich.com

一旦您知道如何使用非常静态数据的教程,您就可以阅读另一篇关于数据库的教程,并简单地将两者结合起来。即使我确信有很多教程可以逐步显示如何将数据加载到数组,显示它,编辑/删除其中的一些数据,并永久地重新保存它。

一旦你对这一切感到满意,你就可以开始阅读有关核心数据的内容(起初有点难以处理,但非常惊人),或者仅仅是FMDBSQLite。如果我可以给你一个建议,不要单独使用Sqlite,使用FMDB包装器。从头开始编写sqlite3只是一个巨大的痛苦。

希望这会有所帮助。 :)

答案 1 :(得分:0)

  1. 在你的detailviewcontroller中你可以将toDoItem设置为弱属性......
  2. 在你的mainviewcontroller的didselectrow实例化你的detailviewcontroller之后你可以将它的todoitem设置为来自你的mainviewcontroller的给定索引路径的todoitem
  3. 在您的detailviewcontroller中,您正在使用mainviewcontroller中的项目和

    1. 在你的unwind segue中你唯一要做的就是重新加载tableviews数据。
    2. 希望你明白我的意思:)。