Как использовать CGBlendMode на UIView, который прокручивается над фиксированным фоном? - PullRequest
3 голосов
/ 01 февраля 2011

Нашим основным UIView является UIScrollView с фиксированным фоновым изображением (очевидно, очень распространенным).В этом scrollView у нас есть несколько UIViews, которые содержат контент и прокручивают вверх и вниз по мере прокрутки пользователем (также часто).Каждый из этих UIViews имеет свой собственный фон, простой градиент от белого к черному.

Цель состоит в том, чтобы сделать градиент фона этих (внутренних) UIViews частично непрозрачными И использовать CGBlendMode, отличный от "kCGBlendModeNormal" (в частности,"kCGBlendModeOverlay").Вы должны видеть сквозное фиксированное фоновое изображение «родительского» scrollView, когда UIViews прокручивают вверх и вниз над ним.

- (void)drawRect:(CGRect)rect {
    gradientStart = [UIColor colorWithRed:1 green:1 blue:1 alpha:1.0];
    gradientEnd = [UIColor colorWithRed:0 green:0 blue:0 alpha:1.0];

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGFloat locations[2] = { 0.0f, 1.0f };
    NSArray *colors = [NSArray arrayWithObjects:(id)gradientStart.CGColor, (id)gradientEnd.CGColor, nil];

    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)colors, locations);
    CGColorSpaceRelease(colorSpace);

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetAlpha(context, 0.50); //this works!
    CGContextSetBlendMode(context, kCGBlendModeOverlay); //doesn’t seem to do anything!

    CGContextClearRect(context, rect);

    CGPoint startPoint, endPoint;
    startPoint.x = 0.0;
    startPoint.y = 0.0;
    endPoint.x = 0.0;
    endPoint.y = rect.size.height;

    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);

    CGGradientRelease(gradient);

    [super drawRect:rect];
}

Все работает, как и ожидалось, кроме CGContextSetBlendMode, который игнорируется.Похоже, мы не можем найти способ изменить blendMode UIView относительно того, что стоит за ним, так же, как вы можете это сделать с alpha.Обратите внимание, что это отличается от создания нескольких слоев в ОДНОМ UIView;в этом случае этот метод изменяет blendMode слоев "сверху".Мы хотим видеть фиксированное фоновое изображение родительского scrollView (когда мы прокручиваем дочерний вид вверх и вниз над ним), применяя как альфа, так и наложение.

Вот изображение, показывающее проблему: http://img2.sbck.us/blendmode.png

Заранее спасибо за помощь!

Ответы [ 3 ]

4 голосов
/ 01 февраля 2011

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

2 голосов
/ 11 января 2012

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

  1. Определить прямоугольник для вида переднего плана.
  2. Преобразовать прямоугольник в виде переднего плана в прямоугольник вфоновый вид.
  3. Начните новый графический контекст.
  4. Нарисуйте фон в правильном режиме наложения.
  5. Нарисуйте передний план с правильным режимом наложения.
  6. Извлеките изображение из графического контекста.
  7. Завершите графический контекст.
  8. Используйте извлеченное изображениесоответственно.

Это позволяет изображению переднего плана сливаться с фоновым изображением.

0 голосов
/ 05 мая 2011

Похоже, вы могли бы сделать это, установив свойство 'compositingFilter' CALayer вашего представления. Комментарий в CALayer.h гласит: «Объект фильтра, используемый для компоновки слоя с его (возможно, отфильтрованным) фоном. Значение по умолчанию равно nil, что подразумевает компоновку исходного кода».

Увы, CoreImage, который предоставляет фильтры, (официально) недоступен на iOS.

Полагаю, другой вашей альтернативой было бы использование OpenGL. Вы все еще можете использовать UIView с OpenGL после моды, визуализируя ваши UIView в изображения, которые затем можно использовать текстуры.

...