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

Я создал пользовательскую ячейку в файле UITableView. Стиль установлен на Пользовательский. Идентификатор установлен на customCell. Аксессуар установлен на Деталь. Содержимое табличного представления настроено на динамические прототипы.

Таблица загружается данными из основных данных и выглядит идеально при первом появлении. Когда пользователь нажимает значок сведений в ячейке, появляется переход к новому представлению, чтобы пользователь мог редактировать данные в ячейке и сохранять их в основных данных. Когда пользователь закончит редактирование и нажмет кнопку «Сохранить», представление вернется к UITableView, но только что отредактированная ячейка появится как «базовая», а не как customCell. Если я нажму на ячейку, она подсветится, и пользовательское содержимое ячейки появится НАД основным содержимым ячейки.

Кажется, я не могу решить это. Кто-нибудь может что-нибудь предложить?

Вот часть prepareForSegue, которая отправляет в контроллер представления редактирования:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell*)sender {

if ([[segue identifier]isEqualToString:@"editPunchItemSegue"]) {
// DEFINE SEGUE DESTINATION
UINavigationController *navigationController = segue.destinationViewController;
EditPunchItemViewController *editPunchItemViewController = (EditPunchItemViewController*)navigationController.topViewController;

NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
Punchitem *editPunchItem = (Punchitem*)[self.fetchedResultsController objectAtIndexPath:indexPath];

editPunchItemViewController.editPunchitem = editPunchItem;

А теперь в целевом контроллере представления, где редактируются основные данные, вот часть метода saveButtonPressed:

 if  ([_editSaveButton.title isEqualToString:@"Save"]) {
    NSLog(@"Save Button has been PRESSED");

    editPunchitem.punchitemRoomNumber = _editPunchitemRoomNumberField.text;
    editPunchitem.punchitemDescription = _editPunchitemDescriptionField.text;
    editPunchitem.punchitemLocation = _editPunchitemLocationField.text;
    editPunchitem.punchitemRoomName = _editPunchitemRoomNameField.text;
    editPunchitem.punchitemDate = _editPunchitemDateField.text;

    // SAVE TO MANAGE OBJECT CONTEXT!
    [super saveAndDismiss];
}

Какие-либо предложения?

Вот мой cellForRowAtIndex в TableViewController

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"Running %@ '%@'", self.class, NSStringFromSelector(_cmd));

    static NSString *CellIdentifier = @"customCell";

//  USING CUSTOM PROTOTYPE CELL:
    CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...
    Punchitem *punchitem = [self.fetchedResultsController objectAtIndexPath:indexPath];

//  USING CUSTOM PROTOTYPE CELL:
    cell.cellLocationLabel.text = punchitem.punchitemLocation;
    cell.cellDescriptionLabel.text = punchitem.punchitemDescription;
    cell.cellRoomNameLabel.text = punchitem.punchitemRoomName;

    return cell;
}

Сохранить и закрыть является частью подкласса. Вот метод:

-(void) saveAndDismiss {

    NSError *error = nil;
    if ([self.managedObjectContext hasChanges]) {
        if (![self.managedObjectContext save:&error]) {  //SAVE FAILED
            NSLog(@"YOUR SAVE FAILED! %@", [error localizedDescription]);
        } else {
            NSLog(@"SAVE SUCCEEDED!");
        }
    }

    [self dismissViewControllerAnimated:YES completion:nil];
}

person Jupiter869    schedule 02.03.2014    source источник
comment
что делает save и dissmiss, и, пожалуйста, покажите cellAtRowIndex, похоже, что-то перезаписывает вашу раскадровку   -  person meda    schedule 02.03.2014
comment
Я только что добавил свой cellForRowAtIndex в исходное сообщение.   -  person Jupiter869    schedule 02.03.2014
comment
Попробуйте использовать ячейку прототипа xib.   -  person Oleg Sobolev    schedule 03.03.2014
comment
очень хорошее решение, найденное для этого в чате.   -  person Sameeksha Kumari    schedule 15.06.2014


Ответы (4)


Вы пытались перезагрузить таблицу, когда вернулись из EditPunchItemViewController?

поместите в основной viewController :

- (void)viewWillAppear:(BOOL)animated {
   if (self.tableView) {
        [self.tableView reloadData];
    }
}
person Armand DOHM    schedule 02.03.2014
comment
Да, у меня есть эта самая строка в viewWillAppear моего TableViewController. К сожалению, это не помогает. - person Jupiter869; 02.03.2014

У вас было что-то подобное

[self.tableView beginUpdates];

Если да, вы обязательно вызовете это, когда закончите

[self.tableView endUpdates];

Большую часть времени мы используем это с NSFetchedResultsController...

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}
...
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}
person Armand DOHM    schedule 02.03.2014
comment
Да, спасибо за это предложение, но оба этих метода уже включены в мой код. - person Jupiter869; 02.03.2014

Последний вариант, вам нужно выполнить условную отладку...

Все в вашем Main ViewController:

1) добавить свойство

@property (strong,nonatomic) NSIndexPath *DEBUGindexPath;

2) установить DEBUGindexPath в

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell*)sender {

if ([[segue identifier]isEqualToString:@"editPunchItemSegue"]) {
...
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
DEBUGindexPath = indexPath;
...

3) Добавьте точку останова в

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

Отредактируйте точку останова, чтобы установить условие:

(self.DEBUGindexPath.row == indexPath.row) && (self.DEBUGindexPath.section == indexPath.section)

Не устанавливайте Автоматически продолжить...

Хорошо, теперь запустите ваше приложение. Когда вы вернетесь из EditPunchItemViewController, точка останова должна срабатывать только для выбранной строки. Идите шаг за шагом, чтобы проверить, можете ли вы что-то найти

person Armand DOHM    schedule 02.03.2014

представление возвращается к UITableView, но только что отредактированная ячейка отображается как «базовая», а не как customCell.

Посмотрите на cellForRowAtIndexPath внимательно, следующее условие:

    //USING CUSTOM PROTOTYPE CELL:
    CustomTableViewCell *cell =
                    [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc]
                             initWithStyle:UITableViewCellStyleDefault 
                           reuseIdentifier:CellIdentifier];
    }

Когда ячейка равна nil, вы устанавливаете ее стиль на UITableViewCellStyleDefault, но вы забываете установить ее вспомогательный тип через код.

Поэтому просто убедитесь, что в этом операторе if установлен тип аксессуара, например:

    //USING CUSTOM PROTOTYPE CELL:
    CustomTableViewCell *cell =
                    [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomTableViewCell alloc]
                             initWithStyle:UITableViewCellStyleDefault 
                           reuseIdentifier:CellIdentifier];
        //Set accessory to Detail
        cell.accessoryType = UITableViewCellAccessoryDetailButton;
    }

Вот полный список стилей:

typedef enum : NSInteger {
   UITableViewCellAccessoryNone,
   UITableViewCellAccessoryDisclosureIndicator,
   UITableViewCellAccessoryDetailDisclosureButton,
   UITableViewCellAccessoryCheckmark,
   UITableViewCellAccessoryDetailButton
} UITableViewCellAccessoryType;
person meda    schedule 02.03.2014
comment
Я не понимаю. Я использую пользовательскую ячейку. Когда табличное представление загружается, я получаю базовое представление вместо своего пользовательского представления. Где мне добавить строку cell.accessoryType = UITableViewCellAccessoryDetailButton, чтобы убедиться, что отображается пользовательская ячейка, а не основная ячейка? Должен ли я использовать что-то другое, кроме UITableViewCellStyleDefault? - person Jupiter869; 03.03.2014
comment
@ Jupiter869 Извините, я не так ясно выразился, смотрите мое редактирование - person meda; 03.03.2014
comment
К сожалению, это не имело никакого эффекта. Когда я возвращаюсь из EditView в TableView, ячейка отображается как основная ячейка с одной строкой данных, а не как customCell, которую я настроил в раскадровке. Если я щелкну ячейку, она подсветится, и «Basic» и «customCell» появятся друг над другом. Похоже, что ячейка «Basic» находится в верхней части «customCell». Меня это сбивает с толку и ужасно расстраивает. - person Jupiter869; 03.03.2014
comment
Этот снимок показывает tableView при первой загрузке: imgur.com/sPoazwi. Следующий снимок показывает tableView после второй загрузки. ячейка отредактирована. Обратите внимание, что в ячейке показан основной формат ячейки: imgur.com/TSFct3J — последнее изображение показывает, что происходит, когда я нажимаю вторая ячейка. CustomCell отображается поверх базовой ячейки: imgur.com/uHtSoon. - person Jupiter869; 03.03.2014
comment
@ Jupiter869 Jupiter869 вы используете прототип ячейки? - person meda; 03.03.2014
comment
мой tableView настроен на динамические прототипы в раскадровке - person Jupiter869; 03.03.2014
comment
давайте продолжим это обсуждение в чате - person meda; 03.03.2014