【发布时间】:2011-03-13 00:03:45
【问题描述】:
是否有可能在 UIView 的每个角落都有颜色的渐变?
【问题讨论】:
-
它是软件——你可以为所欲为。您有更具体的问题吗?
标签: iphone objective-c quartz-graphics gradient
是否有可能在 UIView 的每个角落都有颜色的渐变?
【问题讨论】:
标签: iphone objective-c quartz-graphics gradient
没有内置的方法可以做到这一点,也没有简单的方法可以通过 Quartz 做到这一点。但是,您可以通过 Quartz 创建 4 个不同方向的不同 2-D 渐变,并用垂直运行的黑白渐变遮盖每个渐变。
假设您的颜色定义为:tlColor、trColor、blColor、brColor(用于左上角、右上角等)。
您可能想先在 Acorn 或 Photoshop 中尝试一下……所以在将其转换为代码之前,您可以清楚地了解其中涉及的内容。然后 Quartz 参考 @lxt 指出你有关于渐变的部分(CGGradientRef 就足够了,不要尝试使用阴影),还有一个关于图像蒙版的单独部分。
【讨论】:
我有 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 作为成员并相应地更改此片段。
【讨论】:
这是一个可行的解决方案。
绘制两种颜色渐变时,一个垂直渐变位图蒙版既可以原样使用,也可以镜像使用。
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 */
【讨论】:
要比 Carl 更有帮助,答案是“是”,但如何实现它取决于您想使用的技术。 Quartz梯度系统描述如下:
...但是 OpenGL 是另一种可能性。这将取决于您的应用程序。
【讨论】: