我有一个UIView
,它有3个自定义子视图,其类被调用(现在)LVStemp
并且代表树中的节点。 LVStemp
的帧大于节点本身,因为它还包括一些位于节点外部的绘图(尚未编码)。 LVStemp
有一个名为nodeFrame
的属性,它在主视图的坐标中表示节点本身的框架。
我正在尝试绘制节点并用渐变填充它们。但是渐变是以一种不是我想要的方式剪裁。结果如下:
顶部节点填充正确但底部两个不正确。
在UIView
的超级视图中设置:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 100, 350, 350)];
[self.view addSubview:myView];
LVStemp *node1 = [[LVStemp alloc] init];
node1.frame = CGRectMake(75, 0, 50, 50);
node1.nodeFrame = node1.frame;
node1.backgroundColor = [UIColor clearColor];
[myView addSubview:node1];
LVStemp *node2 = [[LVStemp alloc] init];
node2.frame = CGRectMake(0, 25, 100, 175);
node2.nodeFrame = CGRectMake(0, 150, 50, 50);
node2.backgroundColor = [UIColor clearColor];
[myView addSubview:node2];
LVStemp *node3 = [[LVStemp alloc] init];
node3.frame = CGRectMake(100, 25, 100, 175);
node3.nodeFrame = CGRectMake(150, 150, 50, 50);
node3.backgroundColor = [UIColor clearColor];
[myView addSubview:node3];
}
LVStemp.h
中的代码:
@interface LVStemp : UIView
@property (nonatomic) CGRect nodeFrame;
@end
LVStemp.m
中的代码:
@implementation LVStemp
- (void)drawRect:(CGRect)rect
{
// Build nodeBounds (= nodeFrame converted to self's coordinate system)
CGRect nodeBounds = [self convertRect:self.nodeFrame fromView:self.superview];
// Get CGContextRef
CGContextRef context = UIGraphicsGetCurrentContext();
// Draw node with gradient
[self drawEllipseInRect:nodeBounds withGradient:context];
}
- (void)drawEllipseInRect:(CGRect)rect withGradient:(CGContextRef)context
{
UIGraphicsPushContext(context);
CGFloat colors[] = {
0.1, 0.8, 1.0, 1.0,
0.1, 0.4, 0.9, 1.0
};
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;
CGContextSaveGState(context);
CGContextAddEllipseInRect(context, rect);
CGContextClip(context);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxX(rect));
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient), gradient = NULL;
CGContextRestoreGState(context);
CGContextAddEllipseInRect(context, rect);
CGContextDrawPath(context, kCGPathStroke);
UIGraphicsPopContext();
}
@end
(drawEllipseInRect:withGradient:
改编自here。)
如果我注释掉剪辑部分会发生什么:
//CGContextAddEllipseInRect(context, rect);
//CGContextClip(context);
有什么建议吗?
答案 0 :(得分:1)
上下文被剪裁正确,但您正在错误的位置绘制渐变:
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxX(rect));
更改为使用maxY:
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
但正如你可能已经注意到的那样,笔画被剪裁了。那是因为它们是以给定轮廓为中心绘制的。你可以考虑用一些插图来调用它:
[self drawEllipseInRect:CGRectInset(nodeBounds, lineWidth/2, lineWidth/2) withGradient:context];