使用 swift 在 UIView draw() 中绘制渐变
Draw gradient inside UIView draw() with swift
我想在所有视图中设置渐变背景。
我认为不需要在所有视图控制器中创建视图的 IBOutlet 的方法是从 UIView 创建一个新的 class,在 draw() 中我放入了代码在视图中创建一个 CAGradientLayer。
因此,在界面生成器中,我只需要 select 背景视图并将其 class 设置为我的自定义 class。目前有效。
我的问题是我是否可以毫无问题地做到这一点。有人知道可以吗?
因为继承自 UIView 的模型文件带有注释:
//只有在执行自定义绘图时才覆盖 draw()。
而且我不知道创建图层是否重要。或者如果 draw() 只是用于低级绘图或类似的东西。不知道draw()函数的最佳用法
这是代码:
override func draw(_ rect: CGRect) {
let layer = CAGradientLayer()
layer.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
let color1 = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1)
let color2 = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1)
layer.colors = [color1.cgColor, color2.cgColor]
self.layer.addSublayer(layer)
}
您不应该在 draw
函数中添加 CAGradientLayer。
如果您想向视图添加渐变,那么最简单的方法是使用图层(就像您正在做的那样)但不是这样...
您应该将其作为 init 方法的一部分添加到您的视图中,然后在布局子视图方法中更新其框架。
像这样...
class MyView: UIView {
let gradientLayer: CAGradientLayer = {
let l = CAGradientLayer()
let color1 = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1)
let color2 = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1)
l.colors = [color1.cgColor, color2.cgColor]
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
layer.addSublayer(gradientLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = bounds
}
}
我会创建 UIView 扩展并在需要时应用它。
extension UIView {
func withGradienBackground(color1: UIColor, color2: UIColor, color3: UIColor, color4: UIColor) {
let layerGradient = CAGradientLayer()
layerGradient.colors = [color1.cgColor, color2.cgColor, color3.cgColor, color4.cgColor]
layerGradient.frame = bounds
layerGradient.startPoint = CGPoint(x: 1.5, y: 1.5)
layerGradient.endPoint = CGPoint(x: 0.0, y: 0.0)
layerGradient.locations = [0.0, 0.3, 0.4, 1.0]
layer.insertSublayer(layerGradient, at: 0)
}
}
在这里您可以更改 func 声明以将 startPoint
、endPoint
和 locations
参数指定为变量。
之后就像
一样调用这个方法
gradienView.withGradienBackground(color1: UIColor.green, color2: UIColor.red, color3: UIColor.blue, color4: UIColor.white)
P.S.
请注意,您可以在 colors
数组
中拥有任意多的颜色
您可以使用 @IBDesignable
和 @IBInspectable
从 Storyboard
配置 startColor 和 endColor 属性。如果您想在 draw(_ rect:) 方法中绘制,请使用指定颜色和位置的 CGGradient
而不是 CAGradientLayer。简单渐变 class 和 draw(_ rect: CGRect)
函数看起来像这样
import UIKit
@IBDesignable
class GradientView: UIView {
@IBInspectable var startColor: UIColor = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1)
@IBInspectable var endColor: UIColor = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1)
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()!
let colors = [startColor.cgColor, endColor.cgColor]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colorLocations: [CGFloat] = [0.0, 1.0]
let gradient = CGGradient(colorsSpace: colorSpace,
colors: colors as CFArray,
locations: colorLocations)!
let startPoint = CGPoint.zero
let endPoint = CGPoint(x: 0, y: bounds.height)
context.drawLinearGradient(gradient,
start: startPoint,
end: endPoint,
options: [CGGradientDrawingOptions(rawValue: 0)])
}
}
我想在所有视图中设置渐变背景。
我认为不需要在所有视图控制器中创建视图的 IBOutlet 的方法是从 UIView 创建一个新的 class,在 draw() 中我放入了代码在视图中创建一个 CAGradientLayer。
因此,在界面生成器中,我只需要 select 背景视图并将其 class 设置为我的自定义 class。目前有效。
我的问题是我是否可以毫无问题地做到这一点。有人知道可以吗? 因为继承自 UIView 的模型文件带有注释: //只有在执行自定义绘图时才覆盖 draw()。
而且我不知道创建图层是否重要。或者如果 draw() 只是用于低级绘图或类似的东西。不知道draw()函数的最佳用法
这是代码:
override func draw(_ rect: CGRect) {
let layer = CAGradientLayer()
layer.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
let color1 = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1)
let color2 = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1)
layer.colors = [color1.cgColor, color2.cgColor]
self.layer.addSublayer(layer)
}
您不应该在 draw
函数中添加 CAGradientLayer。
如果您想向视图添加渐变,那么最简单的方法是使用图层(就像您正在做的那样)但不是这样...
您应该将其作为 init 方法的一部分添加到您的视图中,然后在布局子视图方法中更新其框架。
像这样...
class MyView: UIView {
let gradientLayer: CAGradientLayer = {
let l = CAGradientLayer()
let color1 = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1)
let color2 = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1)
l.colors = [color1.cgColor, color2.cgColor]
return l
}()
override init(frame: CGRect) {
super.init(frame: frame)
layer.addSublayer(gradientLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = bounds
}
}
我会创建 UIView 扩展并在需要时应用它。
extension UIView {
func withGradienBackground(color1: UIColor, color2: UIColor, color3: UIColor, color4: UIColor) {
let layerGradient = CAGradientLayer()
layerGradient.colors = [color1.cgColor, color2.cgColor, color3.cgColor, color4.cgColor]
layerGradient.frame = bounds
layerGradient.startPoint = CGPoint(x: 1.5, y: 1.5)
layerGradient.endPoint = CGPoint(x: 0.0, y: 0.0)
layerGradient.locations = [0.0, 0.3, 0.4, 1.0]
layer.insertSublayer(layerGradient, at: 0)
}
}
在这里您可以更改 func 声明以将 startPoint
、endPoint
和 locations
参数指定为变量。
之后就像
一样调用这个方法gradienView.withGradienBackground(color1: UIColor.green, color2: UIColor.red, color3: UIColor.blue, color4: UIColor.white)
P.S.
请注意,您可以在 colors
数组
您可以使用 @IBDesignable
和 @IBInspectable
从 Storyboard
配置 startColor 和 endColor 属性。如果您想在 draw(_ rect:) 方法中绘制,请使用指定颜色和位置的 CGGradient
而不是 CAGradientLayer。简单渐变 class 和 draw(_ rect: CGRect)
函数看起来像这样
import UIKit
@IBDesignable
class GradientView: UIView {
@IBInspectable var startColor: UIColor = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1)
@IBInspectable var endColor: UIColor = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1)
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()!
let colors = [startColor.cgColor, endColor.cgColor]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colorLocations: [CGFloat] = [0.0, 1.0]
let gradient = CGGradient(colorsSpace: colorSpace,
colors: colors as CFArray,
locations: colorLocations)!
let startPoint = CGPoint.zero
let endPoint = CGPoint(x: 0, y: bounds.height)
context.drawLinearGradient(gradient,
start: startPoint,
end: endPoint,
options: [CGGradientDrawingOptions(rawValue: 0)])
}
}