Как вы оптимизируете UIColor на iPhone? - PullRequest
0 голосов
/ 15 апреля 2009

Я создаю простую палитру цветов, управляемую пользовательским ползунком.

Я передаю значение с плавающей точкой из ползунка в метод конструктора UIColor и обновляю цвет фона CALayer по мере изменения значения.

В симуляторе он работает очень плавно, но при работе на устройстве я часто мерцаю.

Это только потому, что все облагается налогом на GPU? Это странно худшее при движении через синий. И изменение значения альфа и яркости мерцает больше, чем изменение насыщенности и оттенка.

Не следует ли передавать произвольные значения с плавающей запятой при изменении значения ползунка? Если нет, как я могу ограничить это меньшим количеством цветов для оптимизации?

Я думал об отключении неявных анимаций для свойства backgroundColor объекта CALayer, но я не уверен, как это сделать.

Существуют ли уловки для оптимизации изменений в UIColor.

Обновление

Я не использую drawRect: или drawInRect:

Я просто изменяю свойство backgroundColor объекта CALayer. Каждый раз, когда вызывается touchesMoved: я беру местоположение, создаю значение с плавающей запятой от 0,0 до 1,0 и передаю сообщение моему делегату об изменении значения и вызываю метод - (void) updateCurrentColor.

Вот пример моей реализации:

@implementation MyCustomSliderView


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    hueLocation = [[touches anyObject] locationInView:self];

    //Smoothing
    if ((hueLocation.x > previousHueLocation.x) && ((hueLocation.x - previousHueLocation.x) > 1.0) && (hueLocation.x - previousHueLocation.x) < 10.0) {
        hueLocation.x = previousHueLocation.x + 1.0;
    }   

    if ((hueLocation.x < previousHueLocation.x) && ((previousHueLocation.x - hueLocation.x) > 1.0) && (previousHueLocation.x - hueLocation.x) < 10.0) {
        hueLocation.x = previousHueLocation.x - 1.0;
    }   

    //Percentage of screen.
    hueValue = hueLocation.x/self.bounds.size.width;

    //Clip to 1.0 & 0.0
    if (hueValue > 1.0) {
        hueValue = 1.0;
    }
    if (hueValue < 0.0) {
        hueValue = 0.0;
    }

    NSLog(@"Value is: %f", hueValue);
    NSLog(@"Location %f", hueLocation.x);   

    previousHueLocation = hueLocation;

    if([delegate respondsToSelector:@selector(updateCurrentColor)]) {
        [delegate updateCurrentColor];
    }

}


@implementation MyViewController

- (void)updateCurrentColor {

    currentColor = [UIColor colorWithHue:hueSliderView.hueValue
                              saturation:saturationSliderView.saturationValue
                              brightness:brightnessSliderView.brightnessValue
                                   alpha:alphaSliderView.alphaValue];

    colorLayer.backgroundColor = currentColor.CGColor;  

}

Сначала я подумал, что это скачки значений из-за неточности сенсорного интерфейса. Функция сглаживания помогла, но она по-прежнему мерцает, особенно со значением альфа, даже когда мое местоположение изменяется только на 1 пиксель. Должен ли я ограничить это ограниченным количеством цветов / значений вместо того, чтобы просто передавать произвольное число с плавающей точкой? Опять же, отлично работает в симуляторе, кажется, просто проблема с производительностью.

Ответы [ 2 ]

2 голосов
/ 27 апреля 2009

Отключение неявных анимаций устраняет мерцание.

Я обновил методы изменения цвета, чтобы цвет фона можно было анимировать при вызове из touchesBegan:, но не неявно анимировать при вызове из touchesMoved:

- (void)updateCurrentColorAnimated:(BOOL)animated {

    currentColor = [UIColor colorWithHue:hueSliderView.hueValue
                              saturation:colorView.saturationValue
                              brightness:colorView.brightnessValue
                                   alpha:alphaSlider.alphaValue];
    if (animated) {

        colorLayer.backgroundColor = currentColor.CGColor;

    }   

    if (!animated) {

        [CATransaction begin];

        [CATransaction setValue:(id)kCFBooleanTrue
                         forKey:kCATransactionDisableActions];


        colorLayer.backgroundColor = currentColor.CGColor;

        [CATransaction commit];

    }

}

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

1 голос
/ 15 апреля 2009

Рисование на iPhone с двойной буферизацией. Если вы начинаете мерцать, это потому, что вы рисуете одно, а потом другое - это не из-за проблем со скоростью.

Я полагаю, вы делаете одну из следующих ошибок:

  • Обновление значения цвета и рисование цветового квадрата несинхронно (поэтому цвет не устанавливается правильно при рисовании InRect:)
  • Не удалось правильно инициализировать / рассчитать ваш цвет (поэтому вы отображаете недопустимые цвета)
  • Стирание или перерисовка прямоугольника, когда вы не должны

Еще одна вещь, которую нужно проверить ... цвета в Какао - это числа с плавающей точкой от нуля до 1. Установка целочисленных значений от 0 до 255 (при использовании в Интернете или Windows) приведет к серьезным странным проблемам. Если ваши цветовые расчеты превышают 0–255, то перед настройкой UIColor делите на 255,0.

...