具有渐变颜色的圆角矩形

发布于 2024-08-14 16:35:12 字数 1139 浏览 7 评论 0原文

我还没有真正使用 Core Graphics 进行过太多编程。现在我倾向于坚持使用 QuartzCore,因为它通过 Layer 属性完成了我需要的很多工作:)

但是,我有一个 UIView,它当前是渐变的。我想向此 UIView 添加圆角,但当我绘制渐变时,layer 属性不会执行此操作:

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

    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 1.0, 1.0, 1.0, 0.95,  // Start color
                            1.0, 1.0, 1.0, 0.60 }; // End color

    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);

    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace);
}

我不太确定应该在 drawRect 方法中在哪里进行舍入。谢谢。

I have not really done much programming with Core Graphics. And I tend to stick with QuartzCore now that it does a lot of what I need through the layer property :)

However, I have a UIView, which is currently gradient. I'd like to add rounded corners to this UIView and the layer property does not do this when I draw the gradient:

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

    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 1.0, 1.0, 1.0, 0.95,  // Start color
                            1.0, 1.0, 1.0, 0.60 }; // End color

    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);

    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace);
}

I am not really sure where I should be rounding in the drawRect method. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黎歌 2024-08-21 16:35:12

您检查过以前的问题帖子吗?我不久前读过一篇关于屏蔽 UIView 的文章。我认为这同样适用于所有使用 drawRect

如何在 iPhone SDK 中将方形图像屏蔽为圆角图像?


这是我所做的,据我所知,它工作得很好。

首先,我从上述帖子中借用了 NilObject 先生的代码片段。

我修改了它以适合一个对象(因为他将其编写为 C 函数而不是方法),

我将 UIView 子类化以创建我自己的自定义视图。我重载 initWithRect: 以使我的背景透明。

所以基本上:

  • 设置透明背景(在init中),否则剪裁会很难看
  • 在drawRect中,先进行裁剪,然后在裁剪区域内进行绘制

以下是一个工作示例:

//
//  TeleView.m
//

#import "TeleView.h"


@implementation TeleView
/**** in init methods, set background to transparent,
      otherwise, clipping shows a black background ****/

- (id) initWithFrame:(CGRect)frame {
    if((self = [super initWithFrame:frame])) {
        [self setBackgroundColor:[UIColor colorWithWhite:0.0f alpha:0.0f]];
    }
    return self;
}
- (void) clipCornersToOvalWidth:(float)ovalWidth height:(float)ovalHeight
{
    float fw, fh;
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect rect = CGRectMake(0.0f, 0.0f, self.frame.size.width, self.frame.size.height);

    if (ovalWidth == 0 || ovalHeight == 0) {
        CGContextAddRect(context, rect);
        return;
    }
    CGContextSaveGState(context);
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM (context, ovalWidth, ovalHeight);
    fw = CGRectGetWidth (rect) / ovalWidth;
    fh = CGRectGetHeight (rect) / ovalHeight;
    CGContextMoveToPoint(context, fw, fh/2);
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
    CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
    CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
    CGContextClosePath(context);
    CGContextRestoreGState(context);
}

-(void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    /**** here is what I modified. ****/
    [self clipCornersToOvalWidth:20.0f height:20.0f];
    CGContextClip(currentContext);

    /**** below this is your own code ****/
    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 1.0, 0.0, 0.0, 0.60,  // Start color
    0.0, 1.0, 0.0, 0.40 }; // End color

    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);

    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace); 

}

@end

Have you checked previous question postings? I read one a while back about masking UIViews. I think the same applies pretty much on all objects which use drawRect

How to mask a square image into an image with round corners in the iPhone SDK?


Here's what I did, and it works fine as far as I can tell.

First, I borrowed Mr NilObject's code snippet from the above mentioned post.

I modified it to fit in an object (as he wrote it as a C function instead of a method)

I subclass UIView to create my own custom view. I overload initWithRect: to make my background transparent.

So basically:

  • set transparent background (in init), or clipping will be uggly
  • in drawRect, first clip, then draw inside the clipped area

The following is a working example:

//
//  TeleView.m
//

#import "TeleView.h"


@implementation TeleView
/**** in init methods, set background to transparent,
      otherwise, clipping shows a black background ****/

- (id) initWithFrame:(CGRect)frame {
    if((self = [super initWithFrame:frame])) {
        [self setBackgroundColor:[UIColor colorWithWhite:0.0f alpha:0.0f]];
    }
    return self;
}
- (void) clipCornersToOvalWidth:(float)ovalWidth height:(float)ovalHeight
{
    float fw, fh;
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect rect = CGRectMake(0.0f, 0.0f, self.frame.size.width, self.frame.size.height);

    if (ovalWidth == 0 || ovalHeight == 0) {
        CGContextAddRect(context, rect);
        return;
    }
    CGContextSaveGState(context);
    CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGContextScaleCTM (context, ovalWidth, ovalHeight);
    fw = CGRectGetWidth (rect) / ovalWidth;
    fh = CGRectGetHeight (rect) / ovalHeight;
    CGContextMoveToPoint(context, fw, fh/2);
    CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
    CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
    CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
    CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
    CGContextClosePath(context);
    CGContextRestoreGState(context);
}

-(void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    /**** here is what I modified. ****/
    [self clipCornersToOvalWidth:20.0f height:20.0f];
    CGContextClip(currentContext);

    /**** below this is your own code ****/
    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t num_locations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };
    CGFloat components[8] = { 1.0, 0.0, 0.0, 0.60,  // Start color
    0.0, 1.0, 0.0, 0.40 }; // End color

    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);

    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
    CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);

    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace); 

}

@end
暮年慕年 2024-08-21 16:35:12
NSArray *colors = [NSArray arrayWithObjects:fromColor.CGColor,toColor.CGColor, nil];

NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
NSNumber *stopTwo = [NSNumber numberWithFloat:1.0];

NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, nil];

CAGradientLayer *headerLayer = [CAGradientLayer layer];
headerLayer.colors = colors;
headerLayer.locations = locations;

headerLayer.borderColor = borderColor.CGColor; // border line color**strong text**
headerLayer.borderWidth = width;// For Thickness of border line
headerLayer.cornerRadius = radius;//For Rounded Corner if You want to make rounded Corner

headerLayer.frame = frame;

[view.layer  insertSublayer:headerLayer atIndex:0];

还要确保导入“QuartzCore”框架

NSArray *colors = [NSArray arrayWithObjects:fromColor.CGColor,toColor.CGColor, nil];

NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
NSNumber *stopTwo = [NSNumber numberWithFloat:1.0];

NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, nil];

CAGradientLayer *headerLayer = [CAGradientLayer layer];
headerLayer.colors = colors;
headerLayer.locations = locations;

headerLayer.borderColor = borderColor.CGColor; // border line color**strong text**
headerLayer.borderWidth = width;// For Thickness of border line
headerLayer.cornerRadius = radius;//For Rounded Corner if You want to make rounded Corner

headerLayer.frame = frame;

[view.layer  insertSublayer:headerLayer atIndex:0];

Also make sure to import "QuartzCore" framework

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文