Как правильно добавлять и удалять объекты в табличном представлении с помощью пользовательских табличных ячеек? - PullRequest
0 голосов
/ 15 декабря 2011

В настоящее время я разрабатываю приложение, которое ведет себя как Messages.app. MasterViewController - это главное представление, в которое загружается таблица с именем контакта, временем и фрагментом самого последнего сообщения. Когда вы нажимаете на конкретную ячейку, она перемещается в DetailViewController, где загружает сообщения, которые я отправил контакту, с последним полным сообщением. Нажатие кнопки «Назад» возвращает к MasterViewController. Нажатие rightBarButtonItem открывает ComposeViewController (модальный), где пользователь может составить сообщение для конкретного контакта. Отличие этого приложения от стандартного Messages.app состоит в том, что у него есть таймер задержки перед отправкой сообщения. ComposeViewController имеет текстовое поле для ввода сообщения, кнопку для выбора контакта, кнопку для выбора временной задержки, кнопку для отправки, кнопку для отмены таймера и кнопку для закрытия ModalViewController.

Я полностью удалил возможность отправки актуального SMS-сообщения. Я только что представил пользователю окно с предупреждением, сообщающее ему / ей, что сообщение было отправлено, и если он / она хочет создать новое. Нажатие на Отмена приведет к закрытию ModalViewController и возврату к MasterViewController.

Проблема в том, что я не могу отобразить строки в таблице, а также могу добавлять и удалять ячейки таблицы.

Вот код внутри viewDidLoad моего MasterViewController:

[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 голосов
/ 16 декабря 2011

Ваш последний фрагмент кода, в котором вы создаете новый экземпляр главного контроллера представления, является проблемой.

Это не тот контроллер представления, который вы ищете. Поскольку вы представили контроллер подробного представления модально, вы можете получить доступ к главному контроллеру через свойство parentViewController подробного контроллера:

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

Другие шаблоны проектирования, которые обычно используются в этой ситуации:

  • Создайте новый объект в главном контроллере и вставьте строку в таблицу перед передачей нового объекта в подробный контроллер для обновления
  • Создайте протокол делегата для подробного контроллера, которому соответствует ваш главный контроллер. Установите делегирование детальных контроллеров на главный контроллер при нажатии на него

Последнее - почти то, что вы делаете для всех практических целей, за исключением того, что ваш подробный контроллер знает больше, чем нужно о главном контроллере (т.е. вы импортируете весь главный .h файл, а не просто знаете, что он соответствует протоколу ).

Что касается вашей структуры данных, я не понимаю, как вы ожидаете, что здесь будет несколько строк - вы сохраняете одно сообщение по умолчанию, а затем создаете массив с этим сообщением. Я знаю, что вы не собираетесь использовать значения по умолчанию, чтобы сохранить это в конце, но я ожидаю увидеть массив словарей, сохраненных в значениях по умолчанию под одним ключом, а затем каждый словарь представляет строку в вашей таблице с различными деталями сохраняются как строки в словаре для вашего сообщения, ключей имени контакта и т. д.

Вы должны сделать изменяемую версию массива, возвращаемую из значений по умолчанию, так как она всегда возвращает неизменный массив.

В вашем методе cellForRow ... вы получите соответствующий словарь из массива и заполните его ячейкой.

При добавлении новой строки вы создадите новый словарь для передачи в ваш детальный контроллер.

При удалении строки вы удаляете соответствующий словарь из массива.

...