iOS方向发光

时间:2013-05-27 05:24:36

标签: ios calayer quartz-graphics

我正在尝试创建一个“迷你地图”。它是一个充满标记的圆圈,我希望圆圈的边框在某些位置发光,以指示用户指示在给定方向上有更多标记超出小地图。

我可以通过在其下方绘制一个半径稍大的蓝色圆圈,给圆圈一个“发光”的蓝色边框。我认为通过给CALayer一个面具,我可以让这个蓝色边框在某些地方比其他地方更明亮。 (我试过给它一个渐变蒙版,它可以工作。)

假设我可以进行正确的计算以确定给定像素应该有多亮(假设标记的位置超出迷你地图的视口),我该如何设置CALayer的各个像素?或者是否有更简单的方法来完成我正在寻找的东西,除了为圆圈中的每个像素进行复杂的alpha值计算?

感谢。

2 个答案:

答案 0 :(得分:1)

这是我的解决方案。我绘制了一系列1像素的弧形,每条弧形都有不同的笔触颜色。

void AddGlowArc(CGContextRef context, CGFloat x, CGFloat y, CGFloat radius, CGFloat peakAngle, CGFloat sideAngle, CGColorRef colorRef){
    CGFloat increment = .05;
    for (CGFloat angle = peakAngle - sideAngle; angle < peakAngle + sideAngle; angle+=increment){
        CGFloat alpha = (sideAngle - fabs(angle - peakAngle)) / sideAngle;
        CGColorRef newColor = CGColorCreateCopyWithAlpha(colorRef, alpha);
        CGContextSetStrokeColorWithColor(context, newColor);
        CGContextAddArc(context, x, y, radius, angle, angle + increment, 0);
        CGContextStrokePath(context);
    }
}

然后,在DrawRect中,

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
AddGlowArc(context, 160, 160, 160, angle, .2, [UIColor colorWithRed:0 green:.76 blue:.87 alpha:1].CGColor);

答案 1 :(得分:0)

这是我[更长]的解决方案,它允许在需要时单独添加每个发光点图层并进行动画处理。将小圆圈添加到较大圆圈的圆周上,并旋转较大的圆圈。即使你回答了这个问题,也很高兴能够解决这个问题

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGPoint circleCenter = CGPointMake(300.f, 300.f);
    CALayer *outerCircle = [self outerCircleToRotateWithCenter:circleCenter andRadius:100.f];
    [self.view.layer addSublayer:outerCircle];

    CGFloat rotationAngleInDeg = 270.f;
    CGFloat rotationAngle = (M_PI * -rotationAngleInDeg)/180.f;

    CATransform3D transform = CATransform3DIdentity;
    transform = CATransform3DRotate(transform, rotationAngle, 0.f, 0.f, -1.f);
    [outerCircle setTransform:transform];
}

使用方法:

- (CALayer *)outerCircleToRotateWithCenter:(CGPoint)circleCenter andRadius:(CGFloat )radius {
    // outer circle
    CAShapeLayer *container = [CAShapeLayer layer];
    UIBezierPath *containerCircle = [UIBezierPath
                            bezierPathWithOvalInRect:CGRectMake(0.f, 0.f, radius, radius)];
    [container setPath:containerCircle.CGPath];
    [container setBounds:CGPathGetBoundingBox(containerCircle.CGPath)];
    [container setPosition:circleCenter];
    [container setAnchorPoint:CGPointMake(0.5f, 0.5f)];
    [container setStrokeColor:[UIColor blackColor].CGColor]; // REMOVE
    [container setFillColor:nil];

    // smaller circle
    CAShapeLayer *circle = [[CAShapeLayer alloc] init];
    [container addSublayer:circle];
    UIBezierPath *circlePath = [UIBezierPath
                            bezierPathWithOvalInRect:CGRectMake(0.f, 0.f, 25.f, 25.f)];
    [circle setPath:circlePath.CGPath];
    [circle setBounds:CGPathGetBoundingBox(circlePath.CGPath)];
    [circle setFillColor:[UIColor orangeColor].CGColor];
    [circle setAnchorPoint:CGPointMake(0.5f, 0.5f)];
    [circle setPosition:CGPointMake(radius/2.f, 0.f)];
    [circle setOpacity:0.4f];

    // shadow
    [circle setShadowOpacity:0.8f];
    [circle setShadowRadius:4.f];
    [circle setShadowOffset:CGSizeMake(0.f, 0.f)];
    [circle setShadowColor:[UIColor orangeColor].CGColor];
    [circle setShadowPath:circlePath.CGPath];

    return container;
}

我猜测可以在单个变换中添加和旋转较小的圆,而不是作为子图层。