2014-04-10 10 views
5

Ich versuche, das nächste Kuriosum zu implementieren: ich ein paar Punkte haben, und ich möchte sie mit SinuswellenSine CAShapeLayer als Maske von CALayer

Next-Methode verknüpfen gibt die Anordnung von Punkten für Herstellung Grundstück:

- (NSArray *)plotPointsBetweenPoint:(CGPoint)pointA andPoint:(CGPoint)pointB { 
    double H = fabs(pointB.y - pointA.y); 
    double L = fabs(pointB.x - pointA.x); 

    NSInteger granularity = 40; 
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:granularity + 1]; 
    for (int i = 0; i <= granularity; ++i) { 
    CGFloat x = M_PI*(float)i/(granularity); 
    CGFloat y = -cosf(x); 
    CGFloat multiplier = pointA.y > pointB.y ? 1 : -1; 
    CGPoint newPoint = CGPointMake(pointA.x + L*(float)i/granularity, pointA.y - multiplier*H*(1.0 + y)/2.0); 
    [array addObject:[NSValue valueWithCGPoint:newPoint]]; 
    } 
    return array; 
} 

Nachdem es schaffe ich die besondere UIBezierPath:

- (UIBezierPath *)sineWaveWithPoints:(NSArray *)points { 
    UIBezierPath *path = [[UIBezierPath alloc] init]; 
    NSMutableArray *array = [NSMutableArray array]; 

    for (int i = 0; i < points.count - 1; ++i) { 
    [array addObjectsFromArray:[self plotPointsBetweenPoint:[points[i] CGPointValue] andPoint:[points[i+1] CGPointValue]]]; 
    } 
    [path moveToPoint:[array[0] CGPointValue]]; 
    for (NSValue *value in array) { 
    CGPoint point = [value CGPointValue]; 
    [path addLineToPoint:point]; 
    } 
    [path closePath]; 
    path.lineWidth = 2.0; 
    [path stroke]; 
    return path; 
} 

Next ich füge diesen Weg mit CAShapeLayer:

CAGradientLayer *gradientLayer = [self gradientLayer]; 
CAShapeLayer *maskLine = [CAShapeLayer layer]; 
maskLine.path = [self sineWaveWithPoints:pointsArray].CGPath; 
maskLine.lineWidth = self.plotWidth; 
gradientLayer.mask = maskLine; 
[self.view.layer addSublayer:gradientLayer]; 

this is what I have in the end

So würde Ich mag zwischen diesen Punkten Gradienten Sinuswelle haben. Was genau ist falsch an meinen Handlungen?

Ideal: enter image description here

+1

Es tut mir leid, aber ich verstehe nicht, was Sie mit "Ich würde gerne Gradienten Sinus zwischen diesen Punkten haben". Kannst du klarstellen, was du meinst, oder vielleicht sogar ein Mock-Up (Beispiel in einem Bildeditor) zeigen, was du zu tun versuchst? –

+0

Sicher. Die Aufgabe besteht darin, ein Diagramm zu erstellen. Die Farbe des y-Werts hängt von der Höhe des Werts ab (z. B. von violett bis gelb). Ich entschied, dass der beste Weg, die Linie mit einem solchen Gradienten zu füllen, darin besteht, einen Gradienten-Layer mit geeigneten Farben zu erzeugen und die setMask-Methode mit dem erstellten Sinus CAShapeLayer durchzuführen. P.S. Ich habe den Renderer mit dem Hauptziel fixiert. – x401om

+0

Den Verlauf mit dem strichenen Pfad maskieren? –

Antwort

2

Das Programm verhält sich korrekt ist - das heißt, es tut genau das, was Sie sagen, es zu tun. Das Problem ist, dass das, was Sie ihm sagen (in Ihrem Code), nicht das ist, was Sie sagen, dass Sie wollen (in Ihren Worten und Bildern in Ihrer Frage).

Das erste, was Sie falsch machen: Sie sagten closePath. Es schließt also den Weg! Das bedeutet, dass, nachdem die Welle gezogen wurde, der letzte Punkt mit einer geraden Linie zum ersten Punkt zurückkehrt und die von Ihnen gezeigte Form ergibt.

Das zweite, was Sie falsch machen: Sie sind nicht in der Lage, die Formebene zu manipulieren. Sie machen einen Vanilla-CAShapeLayer und lassen ihn auf seinen Standardwerten stehen. Nun, die Standardeinstellung ist, dass die fillColor schwarz ist (und keine strokeColor). Du änderst das nicht. Sie erhalten also Ihre (falsche) Form mit Schwarz und ohne Strich, und daher ist die resultierende Maske die Form der Innenseite Ihrer (falschen) Form und gibt die von Ihnen gezeigte Verlaufsform der Maske wieder.