2011-09-30 17 views
10

Ho una UIImageView che mostra un'immagine. Voglio "evidenziare" una parte dell'immagine disegnando un contorno rettangolare arrotondato. Mi piacerebbe avere il contorno disegnato con una linea spessa e tratteggiata che "si anima" variando continuamente dove inizia "l'inizio" della linea.iOS Animate Dashed Rectangle Border

Ho pensato di disegnare un cerchio con l'aspetto desiderato e quindi semplicemente di animarlo, ma ho davvero bisogno di una soluzione rettangolare, quindi è fuori.

Priorità:

sto disegnando il bordo arrotondato rettangolo calcolando 8 punti e disegna 4 linee rette e 4 curve. (Forse questo può essere più facile, ma non è la parte rotta!)

Il mio pensiero è che userò una variabile "offset" che inizia in alto a sinistra del rettangolo arrotondato, dove la curva in alto a sinistra incontra il pezzo dritto in alto. Quindi, incrementerò questo "offset" nella parte superiore del rettangolo arrotondato fino a raggiungere la curva in alto a destra, dopodiché "resetterò" la variabile "offset" al suo valore originale.

Questo funziona praticamente come vorrei, finché non si verifica il "reset". A questo punto, l'animazione è a scatti (tipo previsto), ma sembra anche viaggiare in senso inverso per una piccola parte del tempo, prima di riprendere il movimento "in avanti". Infine, all'inizio/alla fine della mia linea tratteggiata, ottengo un segmento extra lungo sulla linea tratteggiata. So che non possono essere tutti uguali (come si può calcolare?), Ma come posso creare 2 segmenti più brevi anziché 1 segmento più lungo?

Qualcuno ha un'idea di cosa posso fare per ottenere un aspetto di "marcia delle formiche in marcia"? Qualche altra idea su un buon modo (usando l'animazione) chiama l'occhio dell'utente su una particolare area dello schermo? (Ha bisogno di circondare una particolare area senza oscurare esso.)

codice attuale:

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextClearRect(context, rect); 

    // Rounded corner will be 10% of average side length (i.e., (w + h)/2) 
    float averageSide = ([self HighlightRect].size.width + [self HighlightRect].size.height)/2.0; 
    float roundSize = averageSide * 0.10; 

    // offset is a static, class variable 
    offset += roundSize/4.0; 
    if ([WhereIAmView offset] < roundSize) { 
     offset = roundSize; 
    } 
    if ([WhereIAmView offset] > ([self HighlightRect].size.width - roundSize)) { 
     offset = roundSize; 
    } 

    // Set the "main" color of the rounded rectangle 
    UIColor *lineColor = [UIColor colorWithRed:027.0/255.0 green:050.0/255.0 blue:224.0/255.0 alpha:1.0]; 
    CGContextSetStrokeColorWithColor(context, [lineColor CGColor]); 
    CGContextSetLineWidth(context, 16.0); 
    CGFloat pattern[] = {25.0, 5.0}; 
    CGContextSetLineDash(context, offset, pattern, 2); 

    CGRect rRect = [self HighlightRect]; 
    // The top left corner 
    CGPoint topLeft = CGPointMake(rRect.origin.x, rRect.origin.y); 
    // The top right corner 
    CGPoint topRight = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y); 
    // The bottom right corner 
    CGPoint bottomRight = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y + rRect.size.height); 
    // The bottom left corner 
    CGPoint bottomLeft = CGPointMake(rRect.origin.x, rRect.origin.y +  rRect.size.height); 

    // The two points across the top of the rounded rectangle (left to right) 
    CGPoint point1 = CGPointMake(rRect.origin.x + roundSize, rRect.origin.y); 
    CGPoint point2 = CGPointMake(rRect.origin.x + rRect.size.width - roundSize, rRect.origin.y); 
    // The two points along the right of the rounded rectangle (top to bottom) 
    CGPoint point3 = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y + roundSize); 
    CGPoint point4 = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y + rRect.size.height - roundSize); 
    // The two points along the bottom of the rounded rectangle (right to left) 
    CGPoint point5 = CGPointMake(rRect.origin.x + rRect.size.width - roundSize, rRect.origin.y + rRect.size.height); 
    CGPoint point6 = CGPointMake(rRect.origin.x + roundSize, rRect.origin.y + rRect.size.height); 
    // The two points along the left of the rounded rectangle (bottom to top) 
    CGPoint point7 = CGPointMake(rRect.origin.x, rRect.origin.y + rRect.size.height - roundSize); 
    CGPoint point8 = CGPointMake(rRect.origin.x, rRect.origin.y + roundSize); 

    // Move to point 1 
    CGContextMoveToPoint(context, point1.x, point1.y); 
    // Add line to point 2 (this is the straight portion across the top) 
    CGContextAddLineToPoint(context, point2.x, point2.y); 
    // Add curve to point 3 (this is the rounded portion in top right) 
    CGContextAddArcToPoint(context, topRight.x, topRight.y, point3.x, point3.y, roundSize); 
    // Add line to point 4 (this is the straight portion across the right) 
    CGContextAddLineToPoint(context, point4.x, point4.y); 
    // Add curve to point 5 (this is the rounded portion in bottom right) 
    CGContextAddArcToPoint(context, bottomRight.x, bottomRight.y, point5.x, point5.y, roundSize); 
    // Add line to point 6 (this is the straight portion across the bottom) 
    CGContextAddLineToPoint(context, point6.x, point6.y); 
    // Add curve to point 7 (this is the rounded portion in bottom left) 
    CGContextAddArcToPoint(context, bottomLeft.x, bottomLeft.y, point7.x, point7.y, roundSize); 
    // Add line to point 8 (this is the straight portion across the left) 
    CGContextAddLineToPoint(context, point8.x, point8.y); 
    // Add curve to point 1 (this is the rounded portion in top left) 
    CGContextAddArcToPoint(context, topLeft.x, topLeft.y, point1.x, point1.y, roundSize); 

    // Stroke the path 
    CGContextStrokePath(context); 

} 

urto bump bump

+0

vuoi "formiche in marcia" come effetto per un'immagine turno le spalle al muro ?. – Vignesh

risposta

21

provare a utilizzare CAShapeLayer con CGPath della forma.

Il percorso rettangolo arrotondato può essere creato utilizzando il metodo di convenienza di Uibezierpath.

È possibile impostare un motivo di linea per il livello forma. L'animazione della proprietà della linea del livello forma darebbe il valore "marching ants like effect".

shapeLayer = [CAShapeLayer layer]; 
CGRect shapeRect = CGRectMake(0.0f, 0.0f, 200.0f, 100.0f); 
[shapeLayer setBounds:shapeRect]; 
[shapeLayer setPosition:CGPointMake(160.0f, 140.0f)]; 
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]]; 
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setLineWidth:1.0f]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setLineDashPattern: 
[NSArray arrayWithObjects:[NSNumber numberWithInt:10], 
    [NSNumber numberWithInt:5], 
    nil]]; 
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0]; 
[shapeLayer setPath:path.CGPath]; 
[[imageview layer] addSublayer:shapeLayer]; 

La funzione di animazione può essere,

- (void)toggleMarching 
    { 
if ([shapeLayer animationForKey:@"linePhase"]) 
    [shapeLayer removeAnimationForKey:@"linePhase"]; 
else { 
    CABasicAnimation *dashAnimation; 
    dashAnimation = [CABasicAnimation 
        animationWithKeyPath:@"lineDashPhase"]; 

    [dashAnimation setFromValue:[NSNumber numberWithFloat:0.0f]]; 
    [dashAnimation setToValue:[NSNumber numberWithFloat:15.0f]]; 
    [dashAnimation setDuration:0.75f]; 
    [dashAnimation setRepeatCount:10000]; 

    [shapeLayer addAnimation:dashAnimation forKey:@"linePhase"]; 

} 
    } 
+7

Ragazzo! Quel codice sembra familiare, http://www.cimgf.com/2009/10/20/marching-ants-with-core-animation. L'attribuzione sarebbe bella. –

+0

@Matt In realtà intendevo attribuire l'attribuzione pronunciando "marce formiche come effetto" e il collegamento per esso.Ma purtroppo il collegamento è mancato. Ho modificato Grazie a proposito !. – Vignesh

+1

Grazie. Lo apprezzo. –