如何在 iOS 10 中将渐变应用到真实设备上的 UIView
How to apply Gradient to UIView in iOS 10 on a real device
我有此扩展程序可以向 Swift 中的视图添加渐变:
extension UIView {
func addGradientWithColor(colorTop: UIColor, colorButton: UIColor){
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = [colorTop.cgColor, colorButton.cgColor]
self.layer.insertSublayer(gradient, at: 0)
}
}
然后,我在我的 UIViewController 中使用它:
override func viewDidLoad(){
self.view.addGradientWithColor(colorTop: UIColor.red, colorButton: UIColor.clear)
super.viewDidLoad()
}
我运行模拟器,效果很好。但是当我想在真实设备上使用我的应用程序时,渐变不起作用。
PD:我尝试了很多方法来做渐变,但在真实设备上没有任何效果。
问题是当视图大小发生变化时您没有调整层的大小,因此它保持在初始值,这主要取决于视图是如何创建的。
我建议使用 UIView
子类,并在 layoutSubviews
方法中更新图层大小,该方法总是在视图调整大小时调用:
@IBDesignable
open class GradientView: UIView {
@IBInspectable
public var startColor: UIColor = .white {
didSet {
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
setNeedsDisplay()
}
}
@IBInspectable
public var endColor: UIColor = .white {
didSet {
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
setNeedsDisplay()
}
}
private lazy var gradientLayer: CAGradientLayer = {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.bounds
gradientLayer.colors = [self.startColor.cgColor, self.endColor.cgColor]
return gradientLayer
}()
override init(frame: CGRect) {
super.init(frame: frame)
layer.insertSublayer(gradientLayer, at: 0)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
layer.insertSublayer(gradientLayer, at: 0)
}
open override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = bounds
}
}
上面的代码还可以让您调整 Xcode 的开始和结束颜色,这样您就可以估计部署时视图的外观。
试试这个,它对我有用。代码:
let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.frame.size = self.gradientView.frame.size
gradientLayer.colors = [UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor] //Use diffrent colors
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
self.gradientView.layer.addSublayer(gradientLayer)
更多详细解释请看这里:Gradient On UIView
此代码用于Swift 5. [透明|白色混合]
中具有透明背景的渐变
let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.white.withAlphaComponent(0.0).cgColor, UIColor.white.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.frame.size = self.gradientView.frame.size
self.gradientView.layer.addSublayer(gradientLayer)
只需确保您使用的是 color.cgColor
而不是 color
。
使用 @Cristik 和另一个用户 的答案(我找不到谁的答案,所以如果你是那个用户,请告诉我,这样我就可以给你信用)
我知道了(在 storyboard/real device/simulator 中更新并允许垂直或水平):
测试于 Xcode 11,Swift 5:
@IBDesignable class GradientView: UIView {
@IBInspectable
public var firstColor: UIColor = .white {
didSet {
gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor]
setNeedsDisplay()
}
}
@IBInspectable
public var secondColor: UIColor = .white {
didSet {
gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor]
setNeedsDisplay()
}
}
@IBInspectable var vertical: Bool = true {
didSet {
updateGradientDirection()
}
}
lazy var gradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
layer.colors = [firstColor.cgColor, secondColor.cgColor]
layer.startPoint = CGPoint.zero
return layer
}()
// MARK: - Lifecycle
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
applyGradient()
}
override init(frame: CGRect) {
super.init(frame: frame)
applyGradient()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
applyGradient()
}
override func layoutSubviews() {
super.layoutSubviews()
updateGradientFrame()
}
// MARK: - Helper
func applyGradient() {
updateGradientDirection()
layer.sublayers = [gradientLayer]
}
func updateGradientFrame() {
gradientLayer.frame = bounds
}
func updateGradientDirection() {
gradientLayer.endPoint = vertical ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0)
}
}
我有此扩展程序可以向 Swift 中的视图添加渐变:
extension UIView {
func addGradientWithColor(colorTop: UIColor, colorButton: UIColor){
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = [colorTop.cgColor, colorButton.cgColor]
self.layer.insertSublayer(gradient, at: 0)
}
}
然后,我在我的 UIViewController 中使用它:
override func viewDidLoad(){
self.view.addGradientWithColor(colorTop: UIColor.red, colorButton: UIColor.clear)
super.viewDidLoad()
}
我运行模拟器,效果很好。但是当我想在真实设备上使用我的应用程序时,渐变不起作用。
PD:我尝试了很多方法来做渐变,但在真实设备上没有任何效果。
问题是当视图大小发生变化时您没有调整层的大小,因此它保持在初始值,这主要取决于视图是如何创建的。
我建议使用 UIView
子类,并在 layoutSubviews
方法中更新图层大小,该方法总是在视图调整大小时调用:
@IBDesignable
open class GradientView: UIView {
@IBInspectable
public var startColor: UIColor = .white {
didSet {
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
setNeedsDisplay()
}
}
@IBInspectable
public var endColor: UIColor = .white {
didSet {
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
setNeedsDisplay()
}
}
private lazy var gradientLayer: CAGradientLayer = {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.bounds
gradientLayer.colors = [self.startColor.cgColor, self.endColor.cgColor]
return gradientLayer
}()
override init(frame: CGRect) {
super.init(frame: frame)
layer.insertSublayer(gradientLayer, at: 0)
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
layer.insertSublayer(gradientLayer, at: 0)
}
open override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = bounds
}
}
上面的代码还可以让您调整 Xcode 的开始和结束颜色,这样您就可以估计部署时视图的外观。
试试这个,它对我有用。代码:
let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.frame.size = self.gradientView.frame.size
gradientLayer.colors = [UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor] //Use diffrent colors
gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
self.gradientView.layer.addSublayer(gradientLayer)
更多详细解释请看这里:Gradient On UIView
此代码用于Swift 5. [透明|白色混合]
中具有透明背景的渐变 let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.white.withAlphaComponent(0.0).cgColor, UIColor.white.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.frame.size = self.gradientView.frame.size
self.gradientView.layer.addSublayer(gradientLayer)
只需确保您使用的是 color.cgColor
而不是 color
。
使用 @Cristik 和另一个用户 的答案(我找不到谁的答案,所以如果你是那个用户,请告诉我,这样我就可以给你信用)
我知道了(在 storyboard/real device/simulator 中更新并允许垂直或水平):
测试于 Xcode 11,Swift 5:
@IBDesignable class GradientView: UIView {
@IBInspectable
public var firstColor: UIColor = .white {
didSet {
gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor]
setNeedsDisplay()
}
}
@IBInspectable
public var secondColor: UIColor = .white {
didSet {
gradientLayer.colors = [firstColor.cgColor, secondColor.cgColor]
setNeedsDisplay()
}
}
@IBInspectable var vertical: Bool = true {
didSet {
updateGradientDirection()
}
}
lazy var gradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
layer.colors = [firstColor.cgColor, secondColor.cgColor]
layer.startPoint = CGPoint.zero
return layer
}()
// MARK: - Lifecycle
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
applyGradient()
}
override init(frame: CGRect) {
super.init(frame: frame)
applyGradient()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
applyGradient()
}
override func layoutSubviews() {
super.layoutSubviews()
updateGradientFrame()
}
// MARK: - Helper
func applyGradient() {
updateGradientDirection()
layer.sublayers = [gradientLayer]
}
func updateGradientFrame() {
gradientLayer.frame = bounds
}
func updateGradientDirection() {
gradientLayer.endPoint = vertical ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0)
}
}