Ios 如何将CAGradientLayer添加到CAShapeLayer?
我试图将CAGradientLayer添加到CAShapeLayer,但渐变不符合层的形状。相反,渐变采用UIView本身的形状。我最初尝试使用UIBezierPath执行此操作,但也不起作用。我正在尝试在我的形状中加入渐变Ios 如何将CAGradientLayer添加到CAShapeLayer?,ios,swift,Ios,Swift,我试图将CAGradientLayer添加到CAShapeLayer,但渐变不符合层的形状。相反,渐变采用UIView本身的形状。我最初尝试使用UIBezierPath执行此操作,但也不起作用。我正在尝试在我的形状中加入渐变 override func drawRect(rect: CGRect) { let bounds = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
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()
根据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)
}
您可以尝试以下设置以生成以下形状,这只是一个示例,向您展示设置,但这应该可以做到:
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)
要制作此文件:
如果这不起作用,那么告诉我,我会设法把它修好,使它起作用
另外,这里有一个简单的矩形:
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)
这里有一个函数要尝试,你必须搞乱颜色,但你可以输入一个框架:
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)
}
或者您可以使用我自己编写的:)Swift 4第一个形状的版本,从该形状生成此输出:
我之所以发布它,是因为基本上每一行在转换成Swift 4时都发生了变化,转换它只是为了检查它是否有效。这非常有效,尽管当我启动模拟器并单击形状时,它表现出奇怪的行为,但它会改变颜色,有时渐变会消失,留下轮廓。我现在没有分段。也许是我的自动布局限制?这很奇怪,让我看看我是否可以测试它,好吧,我打电话给“CGContextRestoreGState(context)”两次,删除第二个,不确定这是否重要,所以,试一下矩形,它非常简单,是的,你的限制可能会导致问题,我假设你不是有意这么做的。
private func drawShape() {
guard let context = UIGraphicsGetCurrentContext() else {
print("No context, handle me")
return
}
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)
guard let sVGID_1_2 = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [gradientColor3.cgColor, gradientColor4.cgColor] as CFArray, locations: [0, 1]) else {
print("No gradient, handle me")
context.restoreGState()
return
}
context.saveGState()
context.translateBy(x: 198.95, y: 199.4)
context.rotate(by: -30 * CGFloat(Double.pi) / 180)
let polygonPath = UIBezierPath()
polygonPath.move(to: CGPoint(x: 0, y: -145.95))
polygonPath.addLine(to: CGPoint(x: 126.4, y: -72.98))
polygonPath.addLine(to: CGPoint(x: 126.4, y: 72.97))
polygonPath.addLine(to: CGPoint(x: 0, y: 145.95))
polygonPath.addLine(to: CGPoint(x: -126.4, y: 72.98))
polygonPath.addLine(to: CGPoint(x: -126.4, y: -72.97))
polygonPath.close()
context.saveGState()
polygonPath.addClip()
context.drawLinearGradient(sVGID_1_2,
start: CGPoint(x: -126.4, y: -72.97),
end: CGPoint(x: 126.41, y: 72.99),
options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
context.restoreGState()
}