Продвинутые градиенты? - PullRequest
0 голосов
/ 13 марта 2011

Возможно ли иметь градиент, где есть цвет в каждом углу UIView?

Ответы [ 4 ]

2 голосов
/ 13 марта 2011

Нет встроенного способа сделать это, и нет простого способа сделать это через Quartz. Однако вы можете сделать это с помощью Quartz, создав 4 разных двумерных градиента, идущих в разных направлениях, и замаскировав каждый из них черно-белым градиентом, проходящим перпендикулярно.

Предполагается, что ваши цвета определены как: tlColor, trColor, blColor, brColor (для верхнего левого, верхнего правого и т. Д.).

  1. Вертикальный градиент от tlColor (вверху) до blColor (внизу).
  2. Горизонтальный градиент от белого (слева) к черному (справа), преобразовать в изображение, использовать в качестве маски изображения с изображением от # 1.
  3. Вертикальный градиент от trColor (вверху) до brColor (внизу).
  4. Горизонтальный градиент от черного (слева) до белого (справа), преобразовать в изображение, использовать в качестве маски изображения с изображением из # 3.
  5. Горизонтальный градиент от blColor (слева) до trColor (справа).
  6. Вертикальный градиент от белого (вверху) к черному (внизу), преобразовать в изображение, использовать в качестве маски изображения с изображением от # 5.
  7. Горизонтальный градиент от tlColor (слева) до brColor (справа).
  8. Вертикальный градиент от черного (вверху) к белому (внизу), преобразовать в изображение, использовать в качестве маски изображения с изображением от # 7.
  9. Затем просто нарисуйте каждый из 4 результатов в представлении.

Возможно, вы захотите сначала попробовать это в Acorn или Photoshop ... поэтому ясно, что происходит, прежде чем переводить его в код. Затем ссылка Quartz @lxt указала, что у вас есть разделы по градиентам (достаточно CGGradientRef, не пытайтесь использовать затенения) и отдельный раздел по маскам изображений.

1 голос
/ 07 февраля 2012

Вот рабочее решение.

Одна растровая маска с вертикальным градиентом используется как есть, так и отражается при рисовании двух цветовых градиентов.

Компоненты FourTimesRGB - это компоненты R, G, B, A четырех угловых цветов UL, UR, LL и LR, то есть ULR, ULG, ULB, ULA, URR и т. Д.

void DrawFourGradientRect(CGContextRef Cgc,
                          const CGRect * Rect,
                          const CGFloat FourTimesRGBAcomponents[16])
{
   int            w;
   int            h;
   void          *MaskData;
   CGColorSpaceRef GrayCS;
   CGColorSpaceRef CS;
   CGContextRef   BC;           //Bitmap context
   CGFloat        GrayComp[4] = {1.0, 1.0, 0.0, 1.0}; //2 * Gray+Alpha
   CGGradientRef  Gradient;
   CGImageRef     Mask;

   w = Rect->size.width;
   h = Rect->size.height;

   //Start filling with white
   CGContextSetRGBFillColor(Cgc, 1, 1, 1, 1);
   CGContextFillRect(Cgc, *Rect);

   //Then create vertical gradient mask bitmap, white on top, black at bottom
   MaskData = malloc(w * h);
   if (!MaskData)
      return;
   GrayCS = CGColorSpaceCreateDeviceGray();
   if (!GrayCS)
   {
      free(MaskData);
      return;
   }
   BC = CGBitmapContextCreate(MaskData, w, h, 8, w, GrayCS, kCGImageAlphaNone);
   if (!BC)
   {
      CGColorSpaceRelease(GrayCS);
      free(MaskData);
      return;
   }
   Gradient = CGGradientCreateWithColorComponents(GrayCS, GrayComp, NULL, 2);
   if (!Gradient)
   {
      CGContextRelease(BC);
      CGColorSpaceRelease(GrayCS);
      free(MaskData);
      return;
   }
   CGColorSpaceRelease(GrayCS);
   CGContextDrawLinearGradient(BC, Gradient, CGPointZero, CGPointMake(0, h), 0);
   CGGradientRelease(Gradient);
   Mask = CGBitmapContextCreateImage(BC);
   CGContextRelease(BC);
   free(MaskData);
   if (!Mask)
      return;

   //Now draw first horizontal color gradient from UL to UR
   CS = CGColorSpaceCreateDeviceRGB();
   if (!CS)
   {
      CGImageRelease(Mask);
      return;
   }

   CGContextSaveGState(Cgc);
   CGContextTranslateCTM(Cgc, Rect->origin.x, Rect->origin.y);
   CGContextClipToMask(Cgc, CGRectMake(0, 0, w, h), Mask);

   Gradient = CGGradientCreateWithColorComponents(CS,
                                        FourTimesRGBAcomponents, NULL, 2);
   if (Gradient)
   {
      CGContextDrawLinearGradient(Cgc, Gradient, CGPointZero, CGPointMake(w, 0), 0);
      CGGradientRelease(Gradient);
   }

   CGContextRestoreGState(Cgc);

   //Finally draw second horizontal color gradient from LL to LR
   CGContextSaveGState(Cgc);
   CGContextTranslateCTM(Cgc, Rect->origin.x, Rect->origin.y + Rect->size.height);
   CGContextScaleCTM(Cgc, 1, -1);   //Use vertical gradient mask upside-down
   CGContextClipToMask(Cgc, CGRectMake(0, 0, w, h), Mask);

   Gradient = CGGradientCreateWithColorComponents(CS,
                                    FourTimesRGBAcomponents + 8, NULL, 2);
   if (Gradient)
   {
      CGContextDrawLinearGradient(Cgc, Gradient, CGPointZero, CGPointMake(w, 0), 0);
      CGGradientRelease(Gradient);
   }

   CGContextRestoreGState(Cgc);

   CGImageRelease(Mask);
   CGColorSpaceRelease(CS);
}                               /* DrawFourGradientRect                      */
1 голос
/ 26 июня 2011

У меня есть 2 градиента, размещенные по диагонали.С оверлеем-смешиванием

- (void)drawRect:(CGRect)rect 
{
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat locations2[2] = { 1.0, 0.0 };
    CGFloat components[8] = { 
        1.0, 1.0, 0.0, 1.0 ,//Yellow
        0.0, 0.0, 1.0, 1.0};//Blue

    CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    CGPoint point1 = CGPointMake(0, 0);
    CGPoint point2 = CGPointMake(self.bounds.size.width, self.bounds.size.height);
    CGContextDrawLinearGradient(currentContext, gradient, point1, point2, 0);

    CGFloat components1[8]  = { 
        0.0, 1.0, 0.0, 1.0,//Red 
        1.0, 0.0, 0.0, 1.0}; //Green

    gradient = CGGradientCreateWithColorComponents(rgbColorspace, components1, locations2, num_locations);

    CGContextSetBlendMode(currentContext, kCGBlendModeOverlay);

    point1 = CGPointMake(self.bounds.size.width, 0);
    point2 = CGPointMake(0, self.bounds.size.height);

    CGContextDrawLinearGradient(currentContext, gradient, point1, point2, 0);


    CGGradientRelease(gradient);
    CGColorSpaceRelease(rgbColorspace); 
}

Чтобы изменить цвет, вы должны иметь 4 UIColors в качестве элементов в представлении и соответственно изменить этот фрагмент.

0 голосов
/ 13 марта 2011

Чтобы быть немного более полезным, чем Карл, ответ «да», но то, как вы его реализуете, будет зависеть от технологии, которую вы хотите использовать.Кварцевая система градиента описана здесь:

http://developer.apple.com/library/mac/#documentation/graphicsimaging/Conceptual/drawingwithquartz2d/dq_shadings/dq_shadings.html

... но OpenGL - другая возможность.Это будет зависеть от вашей заявки.

...