使用自动布局为 UIView 应用渐变背景
Applying gradient background for UIView using auto layout
我扩展了 UIView 以添加一个 addGradientWithColor() 方法来获取渐变背景:
extension UIView {
func addGradientWithColor() {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = [gradientEndColor.CGColor, gradientStartColor.CGColor]
gradient.startPoint = CGPointMake(1,0)
gradient.endPoint = CGPointMake(0.2,1)
self.layer.insertSublayer(gradient, atIndex: 0)
} }
我的问题是当我 运行 横向模式时,UIView 没有拉伸
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.view.addGradientWithColor() }
我尝试调用 viewDidLayoutSubviews() 但它无法正常工作
这是屏幕截图:
删除 viewDidLayoutSubviews() 后
图层不会自行调整大小。要解决此问题,您应该更改图层框架。这是一种可以实现的方式:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
//Update you're layer based on the new frame
self.view.addGradientWithColor()
}
您可以保存对图层的引用,并在视图 layoutSublayersOfLayer
方法中调整它的框架。这可以在 UIView 子类中外包:
class GradientView: UIView {
private let gradient : CAGradientLayer = CAGradientLayer()
/**
displays a gradient on the view
*/
func addGradient() {
self.gradient.frame = self.bounds
self.gradient.colors = [gradientEndColor.CGColor, gradientStartColor.CGColor]
gradient.startPoint = CGPointMake(1,0)
gradient.endPoint = CGPointMake(0.2,1)
self.layer.insertSublayer(self.gradient, atIndex: 0)
}
/**
resizes the gradient with the view size
*/
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
self.gradient.frame = self.bounds
}
}
您可以子类化 UIView 并在添加渐变的地方重写 drawRect 方法。
已更新为 Swift 4
class GradientView: UIView {
private let gradient : CAGradientLayer = CAGradientLayer()
private let gradientStartColor: UIColor
private let gradientEndColor: UIColor
init(gradientStartColor: UIColor, gradientEndColor: UIColor) {
self.gradientStartColor = gradientStartColor
self.gradientEndColor = gradientEndColor
super.init(frame: .zero)
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
gradient.frame = self.bounds
}
override public func draw(_ rect: CGRect) {
gradient.frame = self.bounds
gradient.colors = [gradientEndColor.cgColor, gradientStartColor.cgColor]
gradient.startPoint = CGPoint(x: 1, y: 0)
gradient.endPoint = CGPoint(x: 0.2, y: 1)
if gradient.superlayer == nil {
layer.insertSublayer(gradient, at: 0)
}
}
}
创建 UIView 后,您只需向该视图添加约束。
受此处解决方案的启发,我创建了以下 class。
使用示例:
// Simple usage. From clear to black.
let gradientView1 = GradientView(colors: [.clear, .black])
// Tweak locations. Here the gradient from red to green will take 30% of the view.
let gradientView2 = GradientView(colors: [.red, .green, .blue], locations: [0, 0.3, 1])
// Create your own gradient.
let gradient = CAGradientLayer()
gradient.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
let gradientView3 = GradientView(gradient: gradient)
class:
import UIKit
/**
* View with a gradient layer.
*/
class GradientView: UIView {
let gradient : CAGradientLayer
init(gradient: CAGradientLayer) {
self.gradient = gradient
super.init(frame: .zero)
self.gradient.frame = self.bounds
self.layer.insertSublayer(self.gradient, at: 0)
}
convenience init(colors: [UIColor], locations:[Float] = [0.0, 1.0]) {
let gradient = CAGradientLayer()
gradient.colors = colors.map { [=11=].cgColor }
gradient.locations = locations.map { NSNumber(value: [=11=]) }
self.init(gradient: gradient)
}
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
self.gradient.frame = self.bounds
}
required init?(coder: NSCoder) { fatalError("no init(coder:)") }
}
我扩展了 UIView 以添加一个 addGradientWithColor() 方法来获取渐变背景:
extension UIView {
func addGradientWithColor() {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = [gradientEndColor.CGColor, gradientStartColor.CGColor]
gradient.startPoint = CGPointMake(1,0)
gradient.endPoint = CGPointMake(0.2,1)
self.layer.insertSublayer(gradient, atIndex: 0)
} }
我的问题是当我 运行 横向模式时,UIView 没有拉伸
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.view.addGradientWithColor() }
我尝试调用 viewDidLayoutSubviews() 但它无法正常工作
这是屏幕截图:
删除 viewDidLayoutSubviews() 后
图层不会自行调整大小。要解决此问题,您应该更改图层框架。这是一种可以实现的方式:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
//Update you're layer based on the new frame
self.view.addGradientWithColor()
}
您可以保存对图层的引用,并在视图 layoutSublayersOfLayer
方法中调整它的框架。这可以在 UIView 子类中外包:
class GradientView: UIView {
private let gradient : CAGradientLayer = CAGradientLayer()
/**
displays a gradient on the view
*/
func addGradient() {
self.gradient.frame = self.bounds
self.gradient.colors = [gradientEndColor.CGColor, gradientStartColor.CGColor]
gradient.startPoint = CGPointMake(1,0)
gradient.endPoint = CGPointMake(0.2,1)
self.layer.insertSublayer(self.gradient, atIndex: 0)
}
/**
resizes the gradient with the view size
*/
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
self.gradient.frame = self.bounds
}
}
您可以子类化 UIView 并在添加渐变的地方重写 drawRect 方法。
已更新为 Swift 4
class GradientView: UIView {
private let gradient : CAGradientLayer = CAGradientLayer()
private let gradientStartColor: UIColor
private let gradientEndColor: UIColor
init(gradientStartColor: UIColor, gradientEndColor: UIColor) {
self.gradientStartColor = gradientStartColor
self.gradientEndColor = gradientEndColor
super.init(frame: .zero)
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
gradient.frame = self.bounds
}
override public func draw(_ rect: CGRect) {
gradient.frame = self.bounds
gradient.colors = [gradientEndColor.cgColor, gradientStartColor.cgColor]
gradient.startPoint = CGPoint(x: 1, y: 0)
gradient.endPoint = CGPoint(x: 0.2, y: 1)
if gradient.superlayer == nil {
layer.insertSublayer(gradient, at: 0)
}
}
}
创建 UIView 后,您只需向该视图添加约束。
受此处解决方案的启发,我创建了以下 class。
使用示例:
// Simple usage. From clear to black.
let gradientView1 = GradientView(colors: [.clear, .black])
// Tweak locations. Here the gradient from red to green will take 30% of the view.
let gradientView2 = GradientView(colors: [.red, .green, .blue], locations: [0, 0.3, 1])
// Create your own gradient.
let gradient = CAGradientLayer()
gradient.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
let gradientView3 = GradientView(gradient: gradient)
class:
import UIKit
/**
* View with a gradient layer.
*/
class GradientView: UIView {
let gradient : CAGradientLayer
init(gradient: CAGradientLayer) {
self.gradient = gradient
super.init(frame: .zero)
self.gradient.frame = self.bounds
self.layer.insertSublayer(self.gradient, at: 0)
}
convenience init(colors: [UIColor], locations:[Float] = [0.0, 1.0]) {
let gradient = CAGradientLayer()
gradient.colors = colors.map { [=11=].cgColor }
gradient.locations = locations.map { NSNumber(value: [=11=]) }
self.init(gradient: gradient)
}
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
self.gradient.frame = self.bounds
}
required init?(coder: NSCoder) { fatalError("no init(coder:)") }
}