Требования к операционной системе: iOS 5.0 и выше.
Мобильное устройство: iPad.
В данном примере описывается настройка условного форматирования для ячеек таблицы на основе правила «Значение между A и B». Для применения свойств правила применяется пул настроек условного форматирования.
Для выполнения примера необходимо разместить взамен метода executeExample класса ViewController (см. раздел «Отображение экспресс-отчёта») следующий код:
-(void)executeExample {
MAExpressAnalysisReportViewController *contr = (MAExpressAnalysisReportViewController *)m_controller;
// Получаем массив контроллеров представлений данных
NSArray *controllers =[contr dataViewControllers];
// Определяем значения A и B
double valueA = 7000;
double valueB = 8000;
// Перебираем в цикле контроллеры представлений данных
for(NSObject *controller in controllers)
{
// Проверяем, является ли текущий контроллер контроллером представления данных в виде таблицы
if([controller isMemberOfClass:[MAGridDataViewController class]])
{
// Получаем объект контроллера представления данных в виде таблицы
MAGridDataViewController *gridController = (MAGridDataViewController *)controller;
// Получаем представление контроллера
UIView *view = [gridController view];
// Получаем массив вложенных представлений
NSArray *subviews = [view subviews];
// Перебираем в цикле вложенные представления
for(NSObject *subview in subviews)
{
// Проверяем, является ли текущее представление табличным представлением
if([subview isMemberOfClass:[NuGridView class]])
{
// Получаем объект табличного представления
NuGridView *gridView = (NuGridView *)subview;
// Получаем делегат для работы с таблицей
MAGridDelegate *delegate = (MAGridDelegate*)[gridView gridDelegate];
// Получаем прокси-источник данных
MAGridProxyDataSource *proxyDatasource = (MAGridProxyDataSource*)[delegate proxyDataSource];
// Определяем настройки условного форматирования на базе правил
MAConditionalFormattingRules *rules = [[MAConditionalFormattingRules new] autorelease];
// Правила будем применять для всей таблицы
[rules setArea: kCFAEntireTable];
// Получаем правило условного форматирования
MAConditionalFormattingRule *formattingRule = [rules ruleByType: kCFRTBetween];
// Помечаем созданное правило как активное
[formattingRule setActive: YES];
// Устанавливаем цвет заливки для ячеек, удовлетворяющих правилу
[formattingRule setColor: [UIColor colorWithRed:1 green:0.77 blue:0.27 alpha:1]];
// Используем абсолютные числовые значения
[formattingRule setValueFormat: kCFRVFNumber];
// Разрешаем использовать сортировку данных
[formattingRule setApplyOrder: YES];
// Создаём пул настроек условного форматирования
MAConditionalFormattingPool *formattingPool = [[MAConditionalFormattingPool new] autorelease];
// Устанавливаем пул для правила условного форматирования
[formattingRule setConditionalFormattingPool: formattingPool];
// Инициализируем объект с предопределёнными данными
MAConditionalFormattingRulePreparedData *preparedData = [[MAConditionalFormattingRulePreparedData new] autorelease];
NSMutableArray *dataArray = nil; // Массив данных
double total = 0.0; // Общая сумма значений данных
// Проверяем, требуется ли подготовка настроек для правила условного форматирования
bool isNeedPrepareData = [formattingRule needPrepareDataForCellInRow:nil andColumn:nil withArea:[rules area]];
if (isNeedPrepareData) {
// Подготавливаем данные
[preparedData setPreparedValueA: [NSNumber numberWithDouble: valueA]];
[preparedData setPreparedValueB: [NSNumber numberWithDouble: valueB]];
// Записываем подготовленные данные в пул настроек условного форматирования
[formattingPool putPreparedData: preparedData forRuleInRow:nil andColumn:nil withType: [formattingRule type] withArea:kCFAEntireTable];
// Создаём отсортированный массив данных для всей таблицы
dataArray = [self dataArrayForEntireTableForDataSource: proxyDatasource];
[dataArray removeObjectIdenticalTo:[NSNull null]];
[dataArray sortUsingSelector:@selector(compare:)];
// Вычисляем общую сумму данных массива
total = [self calculateDataTotal:dataArray];
if ([formattingRule applyOrder]) {
// Подготавливаем данные для правила условного форматирования
[formattingRule prepareWithSortedDataArray:dataArray
andDataTotal:total
inRow:nil
andColumn:nil
withArea: [rules area]];
}
}
// Создаём помощника для работы с настройками условного форматирования
MAConditionalFormattingHelper *formattingHelper = [[MAConditionalFormattingHelper alloc] initWithProxyDataSource: proxyDatasource];
// Применяем настройки условного форматирования для всей таблицы
[formattingHelper applyGlobalConditionalFormat: rules];
// Получаем среднее значение в интервале (A; B)
double valueA = [[preparedData preparedValueA] doubleValue];
double valueB = [[preparedData preparedValueB] doubleValue];
double averageValue = (valueA + valueB) / 2;
// Определяем, принадлежит ли полученное значение данному интервалу
bool conformsToValue = [formattingRule conformsToValue: [NSNumber numberWithDouble: averageValue]];
NSLog(@"Значение %f %@принадлежит интервалу (%f; %f)", averageValue, (conformsToValue? @"": @"не "),
valueA, valueB);
// Определяем цвет, соответствующий данному интервалу
UIColor *color = [rules colorForValue: [NSNumber numberWithDouble: averageValue]];
const CGFloat *components = CGColorGetComponents([color CGColor]);
if (components != NULL) {
CGFloat r = components[0];
CGFloat g = components[1];
CGFloat b = components[2];
NSString *hexString=[NSString stringWithFormat:@"%02X%02X%02X", (int)(r * 255), (int)(g * 255), (int)(b * 255)];
NSLog(@"Цвет, соответствующий значению %f: #%@", averageValue, hexString);
}
}
}
}
}
}
// Создаёт массив данных для всей таблицы
- (NSMutableArray *)dataArrayForEntireTableForDataSource:(MAGridProxyDataSource *)dataSource {
// Получаем объект, предназначенный для работы с таблицей
SPPLPivotTable pivotTable = dataSource.dataSource.pivotTable;
// Получаем количество строк
int rowCount = pivotTable->leftHeader()->elements()->elementsCount();
// Получаем количество столбцов
int columnCount = pivotTable->topHeader()->elements()->elementsCount();
// Создаём массив данных
NSMutableArray *result = [NSMutableArray arrayWithCapacity:rowCount * columnCount];
for (int r = 0; r < rowCount; ++r) {
SPPLPivotTableHeaderElement leftElement = pivotTable->leftHeader()->elements()->getElementByIndex(r);
BOOL isRowInTotal = pivotTable->leftHeader()->elements()->isElementInTotals(leftElement);
if (isRowInTotal) {
continue;
}
for (int c = 0; c < columnCount; ++c) {
SPPLPivotTableHeaderElement topElement = pivotTable->topHeader()->elements()->getElementByIndex(c);
BOOL isColumnInTotal = pivotTable->topHeader()->elements()->isElementInTotals(topElement);
if (isColumnInTotal) {
continue;
}
// Получаем данные ячейки таблицы
SNID data = pivotTable->getData(r, c);
NSObject *value = (data != NULL) ? (NSObject *)data->nsObject() : nil;
if ([value isKindOfClass:NSNumber.class]) {
// Добавляем значение ячейки в массив
[result addObject:value];
}
}
}
return result;
}
// Вычисляет сумму значений данных из указанного массива
- (double)calculateDataTotal:(NSArray *)dataArray {
double total = 0.0; // Сумма значений всех данных
for (NSNumber *number in dataArray) {
if (![number isEqual:nil]) {
double doubleValue = [number doubleValue];
total += doubleValue;
}
}
return total;
}
В результате выполнения примера для всей таблицы экспресс-отчёта было применено условное форматирование с использованием правила «Ячейки между A и B». Так все ячейки, содержащие значения от 7000 до 8000, были окрашены в жёлтый цвет:

В консоли среды разработки были выведены уведомления, принадлежит ли значение 7500 интервалу (7000; 8000), а также цвет заливки ячейки, соответствующий данному значению:
Значение 7500.000000 принадлежит интервалу (7000.000000; 8000.000000)
Цвет, соответствующий значению 7500.000000: #FFC444
Аналогичный результат получим, если заменим фрагмента кода
[formattingRule prepareWithSortedDataArray:dataArray andDataTotal:total inRow:nil andColumn:nil withArea: [rules area]];
на следующий сценарий:
MAConditionalFormattingRulePreparedData *data = [formattingPool preparedDataForRuleInRow:nil andColumn:nil withType:[formattingRule type] withArea: [rules area]]; [formattingRule setValue:data forKey:@"preparedData"]; [formattingRule setValue:[NSNumber numberWithBool: NO] forKey:@"empty"];
После выполнения примера условное форматирование будет применено с теми же настройками.
См. также: