2013-05-27 3 views
1

J'essaie de créer une "mini-carte". C'est un cercle rempli de marqueurs, et je veux que la bordure du cercle brille à certains endroits pour indiquer à l'utilisateur que plusieurs marqueurs dépassent la minicarte dans une direction donnée.iOS Direction Glow

je peux donner le cercle une bordure bleue éclatante »par le dessin, en dessous, un cercle bleu avec un rayon légèrement plus grand. Je pense que je peux rendre cette bordure bleue plus lumineuse dans certains endroits que d'autres en donnant un masque à CALayer. (Je l'ai essayé de donner un masque de gradient, et il fonctionne.)

En supposant que je puisse faire les calculs appropriés pour déterminer comment un pixel donné lumineux doit être (compte tenu de la position des marqueurs au-delà de la fenêtre de la minicarte), comment puis-je définir les pixels individuels d'un CALayer? Ou y a-t-il un moyen plus simple d'accomplir ce que je recherche en plus de faire un calcul de valeur alpha compliqué pour chaque pixel du cercle?

Merci.

+0

Il est difficile (pour moi, de toute façon) pour visualiser l'effet que vous êtes après. Pouvez-vous ajouter une capture d'écran ou un lien vers une capture d'écran? – jrturton

+0

J'ai essayé ma réponse de secteur de cercle (maintenant supprimé) mais c'était un peu de détritus. L'ajout de cercles de cashapelayer avec des ombres à l'extérieur du cercle principal de la carte serait la conjecture suivante. Avez-vous fait quelque progrès? – Steve

+0

J'ai réussi à dessiner un arc en utilisant UIBezierPath, mais le défi sera de faire l'arc le plus brillant (alpha le plus élevé) au milieu et l'évanouissement (alpha le plus bas) près des extrémités. – user2034124

Répondre

1

Voici ma solution. J'ai dessiné une série d'arcs de 1 pixel, chacun avec une couleur de trait différente.

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); 
    } 
} 

Et puis, dans 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); 
0

C'était ma solution [beaucoup plus] qui permettrait d'ajouter et d'animer chaque couche de point lumineux individuellement si nécessaire. Le petit cercle est ajouté sur la circonférence d'un cercle plus grand et ce cercle plus grand est tourné. Nous avons apprécié obtenir ma tête autour de ce même si vous avez répondu à la question

- (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]; 
} 

Utilisation de la méthode:

- (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; 
} 

Je devine que le cercle plus petit pourrait être ajouté et tourné en une seule transformation étant alors plutôt une sous-couche .