高级渐变?

时间:2011-03-13 00:03:46

标签: iphone objective-c quartz-graphics gradient

是否有可能在UIView的每个角落都有颜色的渐变?

4 个答案:

答案 0 :(得分:2)

没有内置的方法来做到这一点,也没有通过Quartz做到这一点的简单方法。但是,您可以通过Quartz创建4个不同方向的2-D渐变,并使用垂直运行的黑白渐变屏蔽每个渐变来实现。

假设您的颜色定义为: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个结果中的每一个绘制到视图中。
  10. 你可能想先在Acorn或Photoshop中尝试这个...所以在将它翻译成代码之前,很清楚它涉及到什么。然后Quartz引用@lxt指向你有关于渐变的部分(CGGradientRef就足够了,不要尝试使用阴影),以及关于图像蒙版的单独部分。

答案 1 :(得分:1)

我有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作为成员,并相应地更改此片段。

答案 2 :(得分:1)

这是一个有效的解决方案。

在绘制两个颜色渐变时,一个垂直渐变位图蒙版既可以原样使用也可以镜像。

FourTimesRGBAcomponents是UL,UR,LL和LR四种角色的R,G,B,A组件,即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                      */

答案 3 :(得分:0)

为了比Carl更有帮助,答案是'是',但是如何实现它将取决于您想要使用的技术。这里描述了Quartz梯度系统:

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

...但OpenGL是另一种可能性。这取决于你的申请。

相关问题