如何使用自定义tableviewcells正确添加和删除tableview的对象?

时间:2011-12-15 10:05:13

标签: arrays xcode dictionary tableview tableviewcell

我目前正在开发一款行为类似于Messages.app的应用。 MasterViewController是主视图,它在其中加载联系人姓名,时间和最新消息片段的表。当您点击特定单元格时,它会滑动到DetailViewController,在那里它将我发送给联系人的消息加载到最新的完整消息中。点击后退按钮返回MasterViewController。点击rightBarButtonItem会打开一个ComposeViewController(模态),用户可以在其中撰写消息给特定联系人。此应用程序与默认Messages.app的区别在于它在发送消息之前有一个延迟计时器。 ComposeViewController有一个用于输入消息的文本字段,用于选择联系人的按钮,用于选择时间延迟的按钮,用于发送按钮的按钮,用于取消计时器的按钮以及用于关闭ModalViewController的按钮。

我删除了完全发送实际短信的功能。我只是向用户提供了一个警报视图,告诉他/她该消息已发送以及他/她是否想要创建一个新消息。点击取消将关闭ModalViewController并返回MasterViewController。

问题是,我无法使行显示在表格中,并且还能够在表格中添加和删除单元格。

这是我的MasterViewController的viewDidLoad中的一些代码:

[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

// Delete button to delete messages
UIBarButtonItem *deleteBarButtonItem = [[UIBarButtonItem alloc] 
                                      initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
                                      target:self 
                                      action:@selector(deleteText)];
self.navigationItem.leftBarButtonItem = deleteBarButtonItem;


// Compose button to go to compose messages
UIBarButtonItem *composeBarButtonItem = [[UIBarButtonItem alloc] 
                                         initWithBarButtonSystemItem:UIBarButtonSystemItemCompose
                                         target:self 
                                         action:@selector(composeText)];
self.navigationItem.rightBarButtonItem = composeBarButtonItem;

[deleteBarButtonItem release];
[composeBarButtonItem release];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *message = [defaults objectForKey:kMessageText];
NSString *contactname = [defaults objectForKey:kContactNameText];
NSString *timestamp = [defaults objectForKey:kTimeStampText];

[messageDetails initWithObjectsAndKeys:contactname, kContactNameKey, message, kContactMsgKey, timestamp, kContactTimeKey, nil];

NSMutableArray *messageInfo = [[NSMutableArray alloc] initWithObjects:messageDetails, nil];

self.messagesList = messageInfo;

[messageInfo release];

[super viewDidLoad];

这是cellForRowAtIndexPath中的代码:

CustomCellViewController *customCell = (CustomCellViewController *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellViewController"];

if (customCell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCellViewController"
                                                 owner:self 
                                               options:nil];
    for (id oneObject in nib) if ([oneObject isKindOfClass:[CustomCellViewController class]])
        customCell = (CustomCellViewController *)oneObject;
}

NSUInteger row = [indexPath row];
NSDictionary *messages = [self.messagesList objectAtIndex:row];

customCell.nameLabel.text = [messages objectForKey:kContactNameKey];
customCell.nameLabel.textColor = [UIColor whiteColor];
customCell.messageLabel.text = [messages objectForKey:kContactMsgKey];
customCell.messageLabel.textColor = [UIColor lightGrayColor];
customCell.timeLabel.text = [messages objectForKey:kContactTimeKey];
customCell.timeLabel.textColor = [UIColor blueColor];

customCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

return customCell;

以下是删除单元格的代码:

- (void)tableView:(UITableView *)tableView commitEditingStyle(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
    // Delete the row from the data source.        
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade];

    [messagesList removeObjectAtIndex:indexPath.row];
    [self.tableView reloadData];
    }
    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.
    }   
}

1 个答案:

答案 0 :(得分:0)

您正在创建主视图控制器的新实例的最终代码段是问题所在。

这不是您正在寻找的视图控制器。由于您已经以模态方式呈现了详细视图控制器,因此可以通过详细控制器的parentViewController属性访问主控制器:

MasterViewController *master = (MasterViewController*)self.parentViewController;

在这种情况下通常使用的其他设计模式:

  • 在主控制器中创建新对象,并在将新对象传递给详细控制器进行更新之前在表中插入行
  • 为主控制器符合的详细控制器创建委托协议。在推动时将详细控制器委托给主控制器

后者几乎就是你为所有实际目的所做的事情,除了你的细节控制器知道的比主控制器更多的东西(即你导入整个主.h文件而不是只知道它符合协议)。

关于您的数据结构,我不明白您希望如何在此处拥有多行 - 您在用户默认值中存储一条消息,然后使用该消息创建一个数组。我知道你不打算使用默认值来存储它,但我希望在一个键下看到默认存储的字典数组,然后每个字典代表表中的一行,包含各种细节作为字典中的字符串存储在您的消息,联系人姓名键等。

您必须创建从默认值返回的数组的可变版本,因为它始终返回不可变数组。

在你的cellForRow ...方法中,你将从数组中获取相应的字典并从中填充单元格。

添加新行时,您需要创建一个新字典以传递给您的详细控制器。

删除行时,您将从阵列中删除相关字典。