2015-08-20 4 views
3

Я пытаюсь добавить CAGradientLayer в CAShapeLayer, но градиент не соответствует форме слоя. Вместо этого градиент принимает форму самого UIView. Сначала я попытался с помощью UIBezierPath, но он тоже не работал. Я пытаюсь поместить градиент в мою форму.Как добавить CAGradientLayer в CAShapeLayer?

override func drawRect(rect: CGRect) { 
     let bounds = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height) 
     let center = self.center 

     let path = CAShapeLayer() 
     path.bounds = bounds 
     path.position = CGPoint(x: center.x, y: center.y) 
     //path.backgroundColor = UIColor.redColor().CGColor 
     path.cornerRadius = 20 
     //self.layer.addSublayer(path) 
     let gradientLayer = CAGradientLayer() 
     gradientLayer.frame = path.bounds 
     gradientLayer.colors = [cgColorForRed(209.0, green: 0.0, blue: 0.0), 
      cgColorForRed(255.0, green: 102.0, blue: 34.0), 
      cgColorForRed(255.0, green: 218.0, blue: 33.0), 
      cgColorForRed(51.0, green: 221.0, blue: 0.0), 
      cgColorForRed(17.0, green: 51.0, blue: 204.0), 
      cgColorForRed(34.0, green: 0.0, blue: 102.0), 
      cgColorForRed(51.0, green: 0.0, blue: 68.0)] 
     gradientLayer.startPoint = CGPoint(x:0,y:0) 
     gradientLayer.endPoint = CGPoint(x:0, y:1) 
     path.insertSublayer(gradientLayer, atIndex: 1) 
     self.layer.addSublayer(path) 


    } 

    func cgColorForRed(red: CGFloat, green: CGFloat, blue: CGFloat) -> AnyObject { 
     return UIColor(red: red/255.0, green: green/255.0, blue: blue/255.5, alpha: 1.0).CGColor as AnyObject 
    } 

Первоначально я путь определяется как UIBezierPath прямоугольника с закругленными углами, которые я ищу, чтобы заполнить с градиентом:

 let insetRect = CGRectInset(rect, lineWidth/2, lineWidth/2) 

     let path = UIBezierPath(roundedRect: insetRect, cornerRadius: 10) 

     fillColor.setFill() 
     path.fill() 

     path.lineWidth = self.lineWidth 
     UIColor.blackColor().setStroke() 
     path.stroke() 

Edit от ответа Larcerax в:

class Thermometer: UIView { 

    //@IBInspectable var fillColor: UIColor = UIColor.greenColor() 
    let lineWidth: CGFloat = 2 

    override func drawRect(rect: CGRect) { 

     let context = UIGraphicsGetCurrentContext() 
     let svgid = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [cgColorForRed(209.0, green: 0.0, blue: 0.0), 
      cgColorForRed(255.0, green: 102.0, blue: 34.0), 
      cgColorForRed(255.0, green: 218.0, blue: 33.0), 
      cgColorForRed(51.0, green: 221.0, blue: 0.0), 
      cgColorForRed(17.0, green: 51.0, blue: 204.0), 
      cgColorForRed(34.0, green: 0.0, blue: 102.0), 
      cgColorForRed(51.0, green: 0.0, blue: 68.0)], [0,1]) 
     CGContextSaveGState(context) 
     let insetRect = CGRectInset(rect, lineWidth/2, lineWidth/2) 

     let path = UIBezierPath(roundedRect: insetRect, cornerRadius: 10) 
     path.addClip() 
     CGContextDrawLinearGradient(context, svgid, CGPoint(x: 0, y: path.bounds.height), 
      CGPoint(x: path.bounds.width, y: path.bounds.height), 
      UInt32(kCGGradientDrawsBeforeStartLocation) | UInt32(kCGGradientDrawsAfterEndLocation)) 
     CGContextRestoreGState(context) 
} 

ответ

4

Вы можете попробовать что-то вроде следующей настройки, чтобы создать следующую форму, это просто пример, чтобы показать вам настройки, но это должно сделать это:

let context = UIGraphicsGetCurrentContext() 

    let gradientColor3 = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000) 
    let gradientColor4 = UIColor(red: 0.000, green: 1.000, blue: 0.000, alpha: 1.000) 

    let sVGID_1_2 = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [gradientColor3.CGColor, gradientColor4.CGColor], [0, 1]) 

    CGContextSaveGState(context) 
    CGContextTranslateCTM(context, 198.95, 199.4) 
    CGContextRotateCTM(context, -30 * CGFloat(M_PI)/180) 

    var polygonPath = UIBezierPath() 
    polygonPath.moveToPoint(CGPointMake(0, -145.95)) 
    polygonPath.addLineToPoint(CGPointMake(126.4, -72.98)) 
    polygonPath.addLineToPoint(CGPointMake(126.4, 72.97)) 
    polygonPath.addLineToPoint(CGPointMake(0, 145.95)) 
    polygonPath.addLineToPoint(CGPointMake(-126.4, 72.98)) 
    polygonPath.addLineToPoint(CGPointMake(-126.4, -72.97)) 
    polygonPath.closePath() 
    CGContextSaveGState(context) 
    polygonPath.addClip() 
    CGContextDrawLinearGradient(context, sVGID_1_2, 
     CGPointMake(-126.4, -72.97), 
     CGPointMake(126.41, 72.99), 
     UInt32(kCGGradientDrawsBeforeStartLocation) | UInt32(kCGGradientDrawsAfterEndLocation)) 
    CGContextRestoreGState(context) 

производить это:

enter image description here

Если это не сработает, то скажите мне, я буду стараться, чтобы исправить его, чтобы заставить его работать.

Кроме того, здесь всего лишь простой прямоугольник:

let context = UIGraphicsGetCurrentContext() 

let gradientColor = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000) 
let gradientColor2 = UIColor(red: 0.988, green: 0.933, blue: 0.129, alpha: 1.000) 
let gradientColor3 = UIColor(red: 1.000, green: 0.000, blue: 1.000, alpha: 1.000) 

let sVGID_1_3 = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [gradientColor.CGColor, gradientColor2.CGColor, gradientColor3.CGColor], [0, 0.43, 1]) 

let rectanglePath = UIBezierPath(rect: CGRectMake(68, 28, 78.4, 78.4)) 
CGContextSaveGState(context) 
rectanglePath.addClip() 
CGContextDrawLinearGradient(context, sVGID_1_3, 
    CGPointMake(68, 67.19), 
    CGPointMake(146.38, 67.19), 
    UInt32(kCGGradientDrawsBeforeStartLocation) | UInt32(kCGGradientDrawsAfterEndLocation)) 
CGContextRestoreGState(context) 

enter image description here

вот функция, чтобы попробовать, вам придется возиться с цветами, но вы можете ввести кадр:

class func drawStuff(#frame: CGRect) { 
     let context = UIGraphicsGetCurrentContext() 

     let gradientColor = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000) 
     let gradientColor2 = UIColor(red: 0.988, green: 0.933, blue: 0.129, alpha: 1.000) 
     let gradientColor3 = UIColor(red: 1.000, green: 0.000, blue: 1.000, alpha: 1.000) 

     let sVGID_1_4 = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [gradientColor.CGColor, gradientColor2.CGColor, gradientColor3.CGColor], [0, 0.43, 1]) 

     let rectangleRect = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height) 
     let rectanglePath = UIBezierPath(rect: rectangleRect) 
     CGContextSaveGState(context) 
     rectanglePath.addClip() 
     CGContextDrawLinearGradient(context, sVGID_1_4, CGPointMake(rectangleRect.minX, rectangleRect.midY),CGPointMake(rectangleRect.maxX, rectangleRect.midY), 0) 
     CGContextRestoreGState(context) 
    } 
+0

Это отлично работает, хотя при запуске симулятора он проявляет странное поведение и нажимает на форму, он меняет цвет, а иногда градиент исчезает, оставляя контур. На данный момент у меня нет переходов. Может быть, это мои ограничения макета авто? – wxcoder

+0

Это странно, позвольте мне посмотреть, могу ли я проверить его – Loxx

+0

дерьмо, ну, я звоню в «CGContextRestoreGState (контекст)» два раза, удаляю второй, не уверен, что это имеет значение – Loxx