UIView 和屏幕旋转上的对角渐变背景
Diagonal Gradient background on UIView and Screen Rotation
我正在尝试将 UIView
的背景设置为渐变。我的 UIViewController
的 viewDidLoad
方法中有以下内容:
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.blue70.cgColor, UIColor.blue60.cgColor, UIColor.blue70.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
gradientLayer.frame = self.view.bounds
self.view.layer.insertSublayer(gradientLayer, at: 0)
渐变按预期呈现。但是,当我旋转设备时,渐变不会重绘并且不再正确呈现。从肖像->风景旋转给我留下了右边或左边的空白部分。从风景->肖像旋转给我留下了底部的空白部分。我尝试将此代码移至 viewDidLayoutSubviews
,但这并没有解决问题。关于如何完成此操作的任何建议?
我在这里推荐的是在 viewWillLayoutSubviews() 方法中添加渐变
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.view.addGradiant()
}
但是现在我们必须删除旧层当添加新层和新帧时(以防 Phone 旋转)
然后我们可以先删除图层并添加新图层,就像在这个扩展方法中一样
extension UIView {
func addGradiant() {
let GradientLayerName = "gradientLayer"
if let oldlayer = self.layer.sublayers?.filter({[=11=].name == GradientLayerName}).first {
oldlayer.removeFromSuperlayer()
}
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.blue.cgColor, UIColor.red.cgColor, UIColor.green.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
gradientLayer.frame = self.bounds
gradientLayer.name = GradientLayerName
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
制作 gradientLayer 视图控制器的 属性.
let gradientLayer = CAGradientLayer()
按照与您相同的方式在 viewDidLoad 中添加 gradientLayer。
在 viewWillLayoutSubviews 中设置框架
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
gradientLayer.frame = self.view.bounds
}
虽然您可以按照其他答案的建议进行操作并更新 viewDidLayoutSubviews
中的渐变层边界,但更可重用的方法是制作一个渐变视图 subclass 谁是 layerClass
是一个 CAGradientLayer
。这样的视图将自动调整其层的大小以适合视图(因为渐变层现在是视图的后备层而不是某些子层)并且您只需更改视图的 class 即可在任何地方使用此视图在您的 nib 文件或情节提要中:
class GradientView: UIView {
var colors: [UIColor] = [.red, .white] {
didSet {
setup()
}
}
var locations: [CGFloat] = [0,1] {
didSet {
setup()
}
}
var startPoint: CGPoint = .zero {
didSet {
setup()
}
}
var endPoint: CGPoint = CGPoint(x: 1, y: 1) {
didSet {
setup()
}
}
override class var layerClass : AnyClass { return CAGradientLayer.self }
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
private func setup() {
guard let layer = self.layer as? CAGradientLayer else {
return
}
layer.colors = colors.map { [=10=].cgColor }
layer.locations = locations.map { NSNumber(value: Double([=10=])) }
layer.startPoint = startPoint
layer.endPoint = endPoint
}
}
我正在尝试将 UIView
的背景设置为渐变。我的 UIViewController
的 viewDidLoad
方法中有以下内容:
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.blue70.cgColor, UIColor.blue60.cgColor, UIColor.blue70.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
gradientLayer.frame = self.view.bounds
self.view.layer.insertSublayer(gradientLayer, at: 0)
渐变按预期呈现。但是,当我旋转设备时,渐变不会重绘并且不再正确呈现。从肖像->风景旋转给我留下了右边或左边的空白部分。从风景->肖像旋转给我留下了底部的空白部分。我尝试将此代码移至 viewDidLayoutSubviews
,但这并没有解决问题。关于如何完成此操作的任何建议?
我在这里推荐的是在 viewWillLayoutSubviews() 方法中添加渐变
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.view.addGradiant()
}
但是现在我们必须删除旧层当添加新层和新帧时(以防 Phone 旋转)
然后我们可以先删除图层并添加新图层,就像在这个扩展方法中一样
extension UIView {
func addGradiant() {
let GradientLayerName = "gradientLayer"
if let oldlayer = self.layer.sublayers?.filter({[=11=].name == GradientLayerName}).first {
oldlayer.removeFromSuperlayer()
}
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.blue.cgColor, UIColor.red.cgColor, UIColor.green.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
gradientLayer.frame = self.bounds
gradientLayer.name = GradientLayerName
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
制作 gradientLayer 视图控制器的 属性.
let gradientLayer = CAGradientLayer()
按照与您相同的方式在 viewDidLoad 中添加 gradientLayer。
在 viewWillLayoutSubviews 中设置框架
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
gradientLayer.frame = self.view.bounds
}
虽然您可以按照其他答案的建议进行操作并更新 viewDidLayoutSubviews
中的渐变层边界,但更可重用的方法是制作一个渐变视图 subclass 谁是 layerClass
是一个 CAGradientLayer
。这样的视图将自动调整其层的大小以适合视图(因为渐变层现在是视图的后备层而不是某些子层)并且您只需更改视图的 class 即可在任何地方使用此视图在您的 nib 文件或情节提要中:
class GradientView: UIView {
var colors: [UIColor] = [.red, .white] {
didSet {
setup()
}
}
var locations: [CGFloat] = [0,1] {
didSet {
setup()
}
}
var startPoint: CGPoint = .zero {
didSet {
setup()
}
}
var endPoint: CGPoint = CGPoint(x: 1, y: 1) {
didSet {
setup()
}
}
override class var layerClass : AnyClass { return CAGradientLayer.self }
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
private func setup() {
guard let layer = self.layer as? CAGradientLayer else {
return
}
layer.colors = colors.map { [=10=].cgColor }
layer.locations = locations.map { NSNumber(value: Double([=10=])) }
layer.startPoint = startPoint
layer.endPoint = endPoint
}
}