Назначение разных цветов ячейкам в зависимости от того, какой выбор делает пользователь (используя основные данные)

У меня есть рабочее приложение, которое в основном состоит из следующего:

Используя Core Data, у меня есть 1 контроллер представления таблицы с кнопкой «Добавить», которая модально вызывает новый контроллер представления, предлагая пользователю добавить текст в три поля. Также есть поле выбора, где пользователь должен выбрать между «куплено» и «продано». Когда пользователь нажимает кнопку «Сохранить», запись добавляется в контроллер табличного представления в виде ячейки подзаголовка с заполненной информацией. Сейчас это хорошо работает без аспекта «купи-продай».

Что я хотел бы сделать, так это просто изменить цвет ячейки таблицы, чтобы он был зеленым для проданного и красным для купленного. Таким образом, когда пользователь добавляет информацию, он заполняет необходимые поля, а также выбирает покупку или продажу, а затем при нажатии кнопки «Сохранить» ячейка табличного представления отображает зеленый или красный цвет для каждой записи.

Я добавляю источник данных tableView и методы делегирования сюда, в текущий TableViewController. При этом я в основном изучаю объект «Транзакция» и извлекаю отношения с другими объектами. «Статус» (Куплено/Продано) также находится в сущности, связанной с сущностью транзакции, в ее собственной сущности, называемой «Покупка». Таким образом, транзакция имеет отношение, называемое status.action (действие является обратным атрибутом транзакции).

Вот код до сих пор из TableView:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.transactions.count;
}



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Persons";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    NSManagedObject *transaction = [self.transactions objectAtIndex:indexPath.row];        
    [cell.textLabel setText:[NSString stringWithFormat:@"%@ %@", [transaction valueForKeyPath:@"whoBy.name"], [transaction valueForKeyPath:@"gifting.amount"]]];
    [cell.detailTextLabel setText:[NSString stringWithFormat:@"%@", [transaction valueForKeyPath:@"occasion.title"]]];

    return cell;        
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [self.managedObjectContext deleteObject:[self.transactions objectAtIndex:indexPath.row]];
        [self.transactions removeObjectAtIndex:indexPath.row];
        [self.tableView reloadData];

        NSError *error = nil;
        if (![self.managedObjectContext save:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
            [self.tableView reloadData];
        }
    }

}

Код модального окна, который фактически идет вперед и позволяет пользователю добавлять текст записей (а также выбирать купленные/проданные, которые еще не реализованы), выглядит следующим образом:

NSManagedObjectContext *context = [self managedObjectContext];        
    NSManagedObject *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
    NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
    NSManagedObject *occasionEvent = [NSEntityDescription insertNewObjectForEntityForName:@"Occasion" inManagedObjectContext:context];
    NSManagedObject *amountType = [NSEntityDescription insertNewObjectForEntityForName:@"Gift" inManagedObjectContext:context];
    [person setValue:self.nameTextField.text forKey:@"name"];
    [occasionEvent setValue:self.occasionTextField.text forKey:@"title"];
    [amountType setValue:self.amountTextField.text forKey:@"amount"]; 
    [transaction setValue:person forKey:@"whoBy"];
    [transaction setValue:occasionEvent forKey:@"occasion"];
    [transaction setValue:amountType forKey:@"gifting"]; 

Любая помощь будет оценена по достоинству.

Спасибо


person amitsbajaj    schedule 14.10.2013    source источник
comment
Я бы порекомендовал вырезать/вставить код делегата tableView в ваш исходный пост, так как мне (по крайней мере) сложно понять, что именно вы делаете. Однако вы, вероятно, в конечном итоге получите ссылку на ячейку (cellForRowAtIndexPath), а затем установите цвет этой ячейки. Это мое предположение.   -  person RegularExpression    schedule 14.10.2013
comment
Пожалуйста, опубликуйте cellForRowAtIndexPath: источник.   -  person Arek Holko    schedule 14.10.2013
comment
Уважаемые RegularExpression и Arkadiusz, спасибо за ваши ответы. Приношу свои извинения за то, что не вставил это раньше; Я сделал это сейчас и отредактировал исходный пост. Я надеюсь, что это поможет, и спасибо, что написали!   -  person amitsbajaj    schedule 14.10.2013


Ответы (1)


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

Я бы также рекомендовал использовать NSFetchedResultsController в качестве источника данных. Он предназначен для хорошей работы с Core Data и табличными представлениями, и если вы правильно настроите делегатов, он даже будет реагировать на изменения в модели без какого-либо вмешательства с вашей стороны.

изменить

Следуя комментариям, которые вы добавили, я вижу, в чем проблема.

Core Data хранит объекты, а не значения. Поэтому, когда вы пытаетесь поместить значения в основное хранилище данных, вы сначала превращаете их в объекты. И когда вы получаете объект из основных данных, вам нужно преобразовать его в желаемое значение.

Вы можете увидеть это в том, что вы делаете сами, когда добавляете объекты в свой управляемый объект:

 [transaction setValue:@(self.wasOptions.selectedSegmentIndex == 0) forKey:@"wasReceived"];

Это выражение возвращает BOOL

self.wasOptions.selectedSegmentIndex == 0

BOOl — это значение, которое нельзя сохранить в Core Data, поэтому вы превращаете его в представление NSNumber с помощью:

@(self.wasOptions.selectedSegmentIndex == 0)

Итак, теперь у вас есть объект NSNumber, представляющий значение BOOL YES или NO, хранящееся в основных данных.

Когда вы пытаетесь получить значение для вашего ключа:

 [transaction valueForKey:@"wasReceived"]

Это возвращает представление NSNumber, а не значение BOOL, которое оно представляет.

Чтобы получить фактический BOOL, используйте удобный метод из NSNumber boolValue. Итак, чтобы решить вашу проблему, замените это выражение:

 [transaction valueForKey:@"wasReceived"]

с этим выражением:

[[transaction valueForKey:@"wasReceived"] boolValue]

который возвращает правильное значение BOOL, с которым может работать ваше условное выражение.

person Abizern    schedule 14.10.2013
comment
Уважаемый Abizem, большое спасибо за ваш ответ, и это очень полезно. Теперь у меня есть сегментированный элемент управления, настроенный и добавленный к основным данным, как именно я могу вызвать это из cellForRowAtIndexPath? У меня есть следующее для метки подробного текста, но как мне вызвать этот ключ? [cell.detailTextLabel setText:[NSString stringWithFormat:@%@, [значение транзакцииForKeyPath:@occasion.title]]]; - person amitsbajaj; 15.10.2013
comment
В cellForRow я помещаю следующий код и по какой-то причине получаю только зеленые ячейки ... независимо от того, какой сегмент я выбираю ... есть мысли? NSManagedObject *transaction = [self.transactions objectAtIndex:indexPath.row]; if ([значение транзакцииForKey:@wasReceived]) { cell.contentView.backgroundColor = [UIColor greenColor]; } еще { cell.contentView.backgroundColor = [UIColor redColor]; } - person amitsbajaj; 15.10.2013
comment
Запишите значение [transaction valueForKey:@"wasReceived"] и сообщите мне, что это такое. Меня особенно интересует, показывает ли это, что это BOOL или NSNumber - person Abizern; 15.10.2013
comment
Спасибо - я не совсем уверен, какие значения анализировать в NSLog. Я поставил NSLog(@value = %@, transaction) и получил NSLog каждого результата, который в настоящее время находится в таблице. Когда я прохожу через это, wasReceived имеет значение 0, когда я щелкнул первый параметр в UISegmentController, и 1, когда я щелкнул второй. Я поставил точку останова в операторе if, и на самом деле похоже, что он пропускает это. ManagedObjectSubclass транзакции помещает его как NSNumber *was. - person amitsbajaj; 15.10.2013
comment
Кроме того, мой метод сохранения в другом контроллере представления, который добавляет значения к объектам/атрибутам: NSManagedObject *transaction = [NSEntityDescription insertNewObjectForEntityForName:@Transaction inManagedObjectContext:context]; [транзакция setValue:@(self.wasOptions.selectedSegmentIndex == 0) forKey:@wasReceived]; это правильно? - person amitsbajaj; 15.10.2013
comment
Дорогой Абизерн, с boolValue это отлично сработало. Честно говоря, это был не просто отличный ответ, помогший мне выполнить эту задачу (где теперь, если я выберу первый сегмент, это будет зеленая ячейка, когда я нажму «Сохранить», и красная ячейка, если я нажму другой сегмент), это тот факт, что вы объяснили это так хорошо. Большое спасибо за ваше время с этой проблемой; это огромный опыт обучения для меня, и я рад использовать эти знания вперед. Спасибо еще раз - person amitsbajaj; 15.10.2013
comment
Уважаемый @Abizern, надеюсь, у вас все хорошо. Сейчас я реализовал NSFetchedResultsController, и он работает очень хорошо, но с приведенным выше кодом и цветами он не сочетается с boolValue. Я звоню сейчас, если (transaction.wasReceived), и он выдает ожидаемую ошибку идентификатора, если я поставлю boolValue. Любые предложения будут очень полезны! - person amitsbajaj; 21.10.2013
comment
На самом деле - не волнуйтесь, все в порядке! Пытался if ([transaction.wasReceived] boolValue]) вместо того, чтобы помещать boolValue перед ]. Работает сейчас! - person amitsbajaj; 21.10.2013