NSFetchedResultsChangeMove отображает неправильную метку в пользовательском UITableViewCell - PullRequest
0 голосов
/ 31 марта 2012

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

Я использую NSFetchedResultsController в своем приложении - очень стандартная проблема - и это работает. Два раздела, упорядочены должным образом и т. Д. Когда пользователь касается ячейки в первом разделе (значение BOOL свойства, создающего эти два раздела, переворачивается) - оно перемещается во второй раздел (значение BOOL переворачивается снова) - и наоборот. .. снова, работает отлично.

Здесь моя реализация становится немного прикольной. В конце концов я хочу поддержать iAds - в соответствии с HIG они должны быть размещены внизу экрана ... самый простой способ сделать это - поместить UITableView в UIView, чтобы избежать некоторых логических причин, которые меня сейчас избегают - но это то, что у меня есть - UIView с UITableView.

Я использую Раскадровки с ячейками-прототипами - два, если быть точным. Один используется для добавления контента и действует как разделитель между двумя разделами. Другая ячейка по умолчанию для отображения. Когда я регистрирую IBOutlets для этой ячейки - она ​​выдает исключение (что является проблемой, но я могу обойти это). Поэтому вместо этого я использовал cell.contentView.subviews, чтобы получить элементы, с которыми мне нужно связываться:

    NSArray *cellSubViews = cell.contentView.subviews;
if ([cellSubViews count] == 3) {
    // editing accessory view
    cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator;

    // default background image view
    cell.backgroundView = self.defaultClockCellBackgroundImageView;

    // clock name label
    UILabel *clockNameLabel = [cellSubViews objectAtIndex:2];
    clockNameLabel.text = clock.name;
    clockNameLabel.textColor = (indexPath.section == 0 && ![clock.isAddClockCell boolValue])
    ? [UIColor whiteColor]
    : [UIColor lightTextColor];

    // view child button
    UIButton *viewChildButton = [cellSubViews objectAtIndex:0];
    UIImage *viewChildClocksButtonBackgroundImage;
    if (self.clockForFetch != nil) {
        //NSLog(@"child clocks list - N/A");
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"childcell_blank"];
        viewChildButton.enabled = NO;

    } else if ([clock.childClocks count] < 2) {
        //NSLog(@"add child button");
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"parentcell_addchild"];

    } else if (![clock.isRunning boolValue] 
               || [self totalChildClocksRunning:clock] < 1) {
        //NSLog(@"view child button");
        // children clocks cannot be running while parent is stopped; 
        // therefore, no need to actually check
        // this solves the "wait for cell animation to end" issue 
        // without the need for tableview reload data
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"parentcell_viewchild"];

    } else {
        //NSLog(@"view child running button");
        viewChildClocksButtonBackgroundImage = [UIImage imageNamed:@"parentcell_viewchild_running"];

    }
    [viewChildButton setImage:viewChildClocksButtonBackgroundImage forState:UIControlStateNormal];
    viewChildButton.hidden = NO;

    // view time entries list for clock
    UIButton *detailDisclosureButton = [cellSubViews objectAtIndex:1];
    UIImage *detailDisclosureButtonBackgroundImage = (self.clockForFetch == nil) 
    ? [UIImage imageNamed:@"parentcell_detaildisclosure"] 
    : [UIImage imageNamed:@"childcell_detaildisclosure"];
    [detailDisclosureButton setImage:detailDisclosureButtonBackgroundImage 
                            forState:UIControlStateNormal];
    detailDisclosureButton.hidden = NO;

    if (self.editing) {
        viewChildButton.hidden = YES;
        detailDisclosureButton.hidden = YES;
    }
}

Обратите внимание: до этого метода я использовал отдельный NIB с IBOutlets и мог повторить проблему - только не так последовательно.

Вот таблица с тремя ячейками, которые перемещаются при нажатии (Альфа, Бета и Гамма) ... ах, нет новых изображений, извините - хотелось бы, чтобы они сказали мне, что до того, как я загрузил изображения - войдите в ASCII art:

---------------
|    alpha    |
---------------
|    beta     |
---------------
|    gamma    |
---------------
| *delimiter* |
---------------

Вот таблица после нажатия на ячейки Альфа и Бета:

---------------
|    gamma    |
---------------
| *delimiter* |
---------------
|    beta     |
---------------
|    beta     |
---------------

Однако, если я коснусь пользовательской кнопки раскрытия подробностей в первой ячейке, помеченной «Бета» (которая должна читать Альфа), я получу правильный объект, переданный в подробный вид:

--------------------------------------------
| < back    detail view for alpha     edit |
--------------------------------------------

Итак, контроллер извлеченных результатов обновляется - кажется, что он не настраивается последовательно, когда он обращается к табличному представлению. В приведенном выше методе настройки ячеек я проверил, чтобы увидеть имена объектов, найденных в контроллере, - и они также правильные; т.е. первая бета-ячейка (ячейка для строки с индексным путем 1,0) - это альфа, а не бета, даже если в табличном представлении отображается бета.

Я продолжаю видеть упоминания о пользовательских ячейках, нуждающихся в setNeedsDisplay и / или setNeedsLayout, но я не думаю, что понимаю это одно - хотя я пытался поместить его почти везде, о чем мог подумать в коде. «NSFetchedResultsChangeMove» - это то, что вызывается, когда пользователь нажимает на ячейку - и я пробовал множество вариантов, которые я видел в Интернете (в том числе здесь), чтобы исправить сбои, которые, на мой взгляд, были похожи - безрезультатно.

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

Любая помощь будет принята с благодарностью. И, если здесь есть ответ на этот же вопрос, я прошу прощения за повторение.

1 Ответ

0 голосов
/ 01 апреля 2012

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

  1. У меня есть две разные ячейки прототипа: ячейка по умолчанию и разделитель. Таким образом, вызов настройки ячейки по пути индекса может привести к неожиданным результатам. Поэтому, где бы я ни называл configureCell atIndexPath, я просто вызывал cellForRowAtIndexPath. Например, в моих извлеченных методах таблицы обновлений контроллера результатов я изменил все, чтобы вместо этого вызывать cellForRowAtIndexPath (в частности, случай обновления изменений - который обычно вызывает конфигурацию ячейки для строки по пути индекса:

    case NSFetchedResultsChangeUpdate:
        //NSLog(@"NSFetchedResultsChangeUpdate");
        [self.TJTableView cellForRowAtIndexPath:indexPath];
        break;
    
  2. Марширование через представление содержимого ячейки с использованием подпредставлений, кажется, не выдерживает себя, и это просто не очень элегантный способ делать вещи; Итак, я поместил UITableViewCell в подкласс с настраиваемой ячейкой в ​​соответствии с инструкцией здесь - http://bit.ly/oI2GGW - таким образом я мог подключить IBOutlets и ссылаться на метку и кнопки непосредственно в строке конфигурации в пути индекса.

...