2015-11-18 9 views
6

Mein Bedürfnis ist, 3-farbige Verteilung in einer Ansicht zu zeigen. Also benutze ich folgenden Code.Swift 2.1: CAGradiantLayer Farbort und Verteilung

func drawWithGradientLayer() { 

     // total contains sum of all values contained in segmentValues variable. 
     // I'm using green -> Orange -> Red colors as colors 

     if total == 0 { 
      return 
     } 

     if gradientLayer.superlayer != nil { 
      gradientLayer.removeFromSuperlayer() 
     } 

     var previous: CGFloat = (CGFloat(segmentValues[0])/CGFloat(total)) 
     var locations: [NSNumber] = [previous] 

     for var i=1; i<segmentValues.count; i++ { 
      previous = previous + (CGFloat(segmentValues[i])/CGFloat(total)) 
      locations.append(previous) 
     } 

     locations.append(1.0) // Line may need to be commented 

     gradientLayer = CAGradientLayer() 
     gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height) 

     gradientLayer.startPoint = CGPointMake(0.0, 0.5); 
     gradientLayer.endPoint = CGPointMake(1.0, 0.5); 

     gradientLayer.colors = colors 
     gradientLayer.locations = locations 

     self.layer.insertSublayer(gradientLayer, atIndex: 0) 
} 

Aber Problem ist, dass Farbverläufe nicht entsprechend meinen Anforderungen verteilt werden. Wenn z. B. Werte von [1,0,1] aufweisen, sollte bar 50% rot angezeigt werden & 0% orange und 50% rot. Wenn Werte [0,0,1] sind, sollte nur redColor gezeichnet werden. Wie kann ich dies ohne Gitterlinien erreichen? enter image description here

andere bessere Lösung wird immer geschätzt werden :)

Antwort

9

Der Schlüssel hier ist, wie locations in CAGradientLayer Arbeit zu verstehen:

Die Steigung stoppt als Wert zwischen 0 und 1 angegeben sind. Die Werte müssen monoton ansteigen.

So legen Sie nicht Orte wie [1, 0, 1], sollte aber eher so etwas wie [0.0, 0.33, 0.67, 1.0] verwenden, und die Anzahl der Positionswerte muss die gleiche sein wie Ihre colors zählen.

Um einen Gradienten mit kurzen Farbübergänge zu machen, wie in den Bildern, Sie jede Farbe zweimal wiederholen und die entsprechenden Örtlichkeiten angeben: gradients

So sollte Ihr Code so etwas wie:

gradientLayer.colors = [ 
     UIColor.greenColor().CGColor, UIColor.greenColor().CGColor, 
     UIColor.orangeColor().CGColor, UIColor.orangeColor().CGColor, 
     UIColor.redColor().CGColor, UIColor.redColor().CGColor 
    ] 
    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) 
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) 
    gradientLayer.locations = [0.0, 0.2, 0.3, 0.7, 0.8, 1.0] 

Wenn Sie einen zweifarbigen Farbverlauf erhalten möchten, ohne seine Farben zu ändern, können Sie für einen Wert kleiner als 0 oder für endPoint.x einen Wert von 0 festlegen und mehrere Positionen auf Null setzen, z. B .:

gradientLayer.startPoint = CGPoint(x: -0.01, y: 0.5) 
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) 
    gradientLayer.locations = [0.0, 0.0, 0.0, 0.0, 0.1, 1.0] 

, die ein ähnliches Ergebnis wie diese geben würde:

2-color gradient

+0

Dank. arbeitete wie ein Charme :) –

+0

Können Sie mir bitte sagen, wie können wir das gleiche für Bogen oder Cricle tun? Danke, – Chetan

+0

@Chetan ist es unmöglich, einen kreisförmigen Farbverlauf mit CAGradientLayer zu zeichnen, es muss manuell mit CGContextDrawRadialGradient gezeichnet werden. Alternativ können Sie eine fertige Ansicht wie diese verwenden - https://github.com/maxkonovalov/MKGradientView – maxkonovalov