使用自动布局为 UIView 应用渐变背景
Posted
技术标签:
【中文标题】使用自动布局为 UIView 应用渐变背景【英文标题】:Applying gradient background for UIView using auto layout 【发布时间】:2016-09-19 12:17:39 【问题描述】:我扩展了 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() 后
【问题讨论】:
你检查过这个ios8-auto-layout-and-gradient 为什么你不继承 UIView 并覆盖 drawRect 方法。在该方法中,只需添加渐变。然后在 UIView 中添加您需要的约束即可。 @rob180 谢谢。是的,但没有解决我的问题 @tomCobo 谢谢你的建议,我会试试的 @tomCobo 谢谢你的建议是最好的。请给它作为答案 【参考方案1】:您可以继承 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 后,您只需将约束添加到该视图。
【讨论】:
我要加if (!self.gradient.superlayer) self.layer.insertSublayer(self.gradient, atIndex: 0)
if self.gradient.superlayer != nil
应该是if self.gradient.superlayer == nil
确定是的。谢谢@thijsonline
UIColor 对我不起作用,我不得不改用 CGColor。【参考方案2】:
您可以保存对图层的引用,并在视图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
【讨论】:
【参考方案3】:图层不会自行自动调整大小。要解决此问题,您应该更改图层框架。这是一种实现方式:
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
//Update you're layer based on the new frame
self.view.addGradientWithColor()
【讨论】:
在我的情况下添加了 viewdidlayoutsubviews() 方法。我在同一个视图中得到两个渐变视图。我在问题本身中附上了屏幕截图【参考方案4】:受此处解决方案的启发,我创建了以下类。
用法示例:
// 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)
班级:
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 $0.cgColor
gradient.locations = locations.map NSNumber(value: $0)
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 应用渐变背景的主要内容,如果未能解决你的问题,请参考以下文章