【问题标题】:How to Apply Gradient to background view of iOS Swift App如何将渐变应用到 iOS Swift App 的背景视图
【发布时间】:2014-08-14 08:32:16
【问题描述】:

我正在尝试应用渐变作为视图的背景颜色(故事板的主视图)。代码运行,但没有任何变化。我正在使用 xCode Beta 2 和 Swift。

代码如下:

class Colors {
  let colorTop = UIColor(red: 192.0/255.0, green: 38.0/255.0, blue: 42.0/255.0, alpha: 1.0)
  let colorBottom = UIColor(red: 35.0/255.0, green: 2.0/255.0, blue: 2.0/255.0, alpha: 1.0)

  let gl: CAGradientLayer

  init() {
    gl = CAGradientLayer()
    gl.colors = [ colorTop, colorBottom]
    gl.locations = [ 0.0, 1.0]
  }
}

然后在视图控制器中:

  let colors = Colors()

  func refresh() {
        view.backgroundColor = UIColor.clearColor()
        var backgroundLayer = colors.gl
        backgroundLayer.frame = view.frame
        view.layer.insertSublayer(backgroundLayer, atIndex: 0)
      }
    }
  }

【问题讨论】:

  • 我发布了一个让它变得简单的组件,你可以使用可可豆荚来使用它,我推荐它,因为它非常简单,你可以通过 XCode 上的界面构建器来设置它。查看更多github.com/heuristisk/hkGraddiant
  • 您在 CAGradientLayer 的属性颜色上使用了 UIColor 元素,但您必须改用 CGColor!

标签: ios ios7 swift cagradientlayer


【解决方案1】:

您提供给渐变的颜色必须是CGColor 类型。所以将CGColor 的数组设置为gl.colors

正确的代码是:

class Colors {
    var gl:CAGradientLayer!

    init() {
        let colorTop = UIColor(red: 192.0 / 255.0, green: 38.0 / 255.0, blue: 42.0 / 255.0, alpha: 1.0).cgColor
        let colorBottom = UIColor(red: 35.0 / 255.0, green: 2.0 / 255.0, blue: 2.0 / 255.0, alpha: 1.0).cgColor

        self.gl = CAGradientLayer()
        self.gl.colors = [colorTop, colorBottom]
        self.gl.locations = [0.0, 1.0]
    }
}

【讨论】:

  • 这是关键:gl.frame = view.bounds;
  • 我在分配给.colors 属性时收到此错误fatal error: array element cannot be bridged to Objective-C。这可能有什么问题?
  • 我已经修好了。这是 Swift 中的一个错误,只需将数组存储在具有显式类型 [AnyObject] 的变量中,然后然后将其分配给 .colors 属性。
  • let c: Array = [colorTop, colorBottom]
  • 对于 swift 1.0,语法为 let c: [AnyObject] = [colorTop, colorBottom]
【解决方案2】:

如果你需要改变渐变的方向,你必须使用 startPoint 和 endPoint。

let gradient: CAGradientLayer = CAGradientLayer()

gradient.colors = [UIColor.blue.cgColor, UIColor.red.cgColor]
gradient.locations = [0.0 , 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height)

self.view.layer.insertSublayer(gradient, at: 0)

【讨论】:

  • 您可能面临的一个问题是,当您添加一个子图层时,它可能位于所有其他项目、标签、图像等之上。要克服这个问题,请创建另一个位于所有内容下方的视图,并且将其约束设置为您想要渐变的容器的约束。然后设置要应用于此视图的渐变。然后子视图将被插入到这一层,而不是放在其他任何东西上。
【解决方案3】:

我做了一个 UIView 扩展来为任何视图应用基本渐变

extension UIView {
    func layerGradient() {
        let layer : CAGradientLayer = CAGradientLayer()
        layer.frame.size = self.frame.size
        layer.frame.origin = CGPointMake(0.0,0.0)
        layer.cornerRadius = CGFloat(frame.width / 20)

        let color0 = UIColor(red:250.0/255, green:250.0/255, blue:250.0/255, alpha:0.5).CGColor
        let color1 = UIColor(red:200.0/255, green:200.0/255, blue: 200.0/255, alpha:0.1).CGColor
        let color2 = UIColor(red:150.0/255, green:150.0/255, blue: 150.0/255, alpha:0.1).CGColor
        let color3 = UIColor(red:100.0/255, green:100.0/255, blue: 100.0/255, alpha:0.1).CGColor
        let color4 = UIColor(red:50.0/255, green:50.0/255, blue:50.0/255, alpha:0.1).CGColor
        let color5 = UIColor(red:0.0/255, green:0.0/255, blue:0.0/255, alpha:0.1).CGColor
        let color6 = UIColor(red:150.0/255, green:150.0/255, blue:150.0/255, alpha:0.1).CGColor

        layer.colors = [color0,color1,color2,color3,color4,color5,color6]
        self.layer.insertSublayer(layer, atIndex: 0)
    }
}       

【讨论】:

  • 我可能会误解,但最好让用户将颜色数组传递给该函数,而不是在其中硬编码它们(除非您总是想应用相同的渐变)。跨度>
  • CGPointMake(0.0,0.0) 可以替换为 CGPointZero 为简洁起见
【解决方案4】:

如果你想使用 HEX 而不是 RGBA,只需拖动一个新的空 .swift 并添加下面提到的代码:

     import UIKit

    extension UIColor {
        convenience init(rgba: String) {
            var red:   CGFloat = 0.0
            var green: CGFloat = 0.0
            var blue:  CGFloat = 0.0
            var alpha: CGFloat = 1.0

            if rgba.hasPrefix("#") {
                let index   = advance(rgba.startIndex, 1)
                let hex     = rgba.substringFromIndex(index)
                let scanner = NSScanner(string: hex)
                var hexValue: CUnsignedLongLong = 0
                if scanner.scanHexLongLong(&hexValue) {
                    switch (count(hex)) {
                    case 3:
                        red   = CGFloat((hexValue & 0xF00) >> 8)       / 15.0
                        green = CGFloat((hexValue & 0x0F0) >> 4)       / 15.0
                        blue  = CGFloat(hexValue & 0x00F)              / 15.0
                    case 4:
                        red   = CGFloat((hexValue & 0xF000) >> 12)     / 15.0
                        green = CGFloat((hexValue & 0x0F00) >> 8)      / 15.0
                        blue  = CGFloat((hexValue & 0x00F0) >> 4)      / 15.0
                        alpha = CGFloat(hexValue & 0x000F)             / 15.0
                    case 6:
                        red   = CGFloat((hexValue & 0xFF0000) >> 16)   / 255.0
                        green = CGFloat((hexValue & 0x00FF00) >> 8)    / 255.0
                        blue  = CGFloat(hexValue & 0x0000FF)           / 255.0
                    case 8:
                        red   = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0
                        green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0
                        blue  = CGFloat((hexValue & 0x0000FF00) >> 8)  / 255.0
                        alpha = CGFloat(hexValue & 0x000000FF)         / 255.0
                    default:
                        print("Invalid RGB string, number of characters after '#' should be either 3, 4, 6 or 8")
                    }
                } else {
                    println("Scan hex error")
                }
            } else {
                print("Invalid RGB string, missing '#' as prefix")
            }
            self.init(red:red, green:green, blue:blue, alpha:alpha)
        }
}

同样,拖动另一个空的 .swift 文件并添加下面提到的代码:

    class Colors {
    let colorTop = UIColor(rgba: "##8968CD").CGColor
    let colorBottom = UIColor(rgba: "#5D478B").CGColor

    let gl: CAGradientLayer

    init() {
        gl = CAGradientLayer()
        gl.colors = [ colorTop, colorBottom]
        gl.locations = [ 0.0, 1.0]
    }
}

之后,在视图控制器中,在类下实例化您的“颜色”类,如下所示:

let colors = Colors()

添加新功能:

func refresh() {
        view.backgroundColor = UIColor.clearColor()
        var backgroundLayer = colors.gl
        backgroundLayer.frame = view.frame
        view.layer.insertSublayer(backgroundLayer, atIndex: 0)
    }

在 viewDidLoad 中声明该函数:

refresh()

你完成了:)) 与 RGBA 相比,使用 HEX 太容易了。 :D

【讨论】:

    【解决方案5】:

    Swift3 中试试这个:

     func addGradient(){
    
        let gradient:CAGradientLayer = CAGradientLayer()
        gradient.frame.size = self.viewThatHoldsGradient.frame.size
        gradient.colors = [UIColor.white.cgColor,UIColor.white.withAlphaComponent(0).cgColor] //Or any colors
        self.viewThatHoldsGradient.layer.addSublayer(gradient)
    
    }
    

    【讨论】:

    • gradient.startPoint = CGPoint(x: 0.0, y: 1.0) gradient.endPoint = CGPoint(x: 1.0, y: 1.0) 用于不同的渐变位置。
    • colorWithAlphaComponent 已重命名为 withAlphaComponent
    【解决方案6】:

    用这个自定义类扩展UIView


    GradientView.swift

    import UIKit
    
    class GradientView: UIView {
    
        // Default Colors
        var colors:[UIColor] = [UIColor.redColor(), UIColor.blueColor()]
    
        override func drawRect(rect: CGRect) {
    
            // Must be set when the rect is drawn
            setGradient(colors[0], color2: colors[1])
        }
    
        func setGradient(color1: UIColor, color2: UIColor) {
    
            let context = UIGraphicsGetCurrentContext()
            let gradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [color1.CGColor, color2.CGColor], [0, 1])!
    
            // Draw Path
            let path = UIBezierPath(rect: CGRectMake(0, 0, frame.width, frame.height))
            CGContextSaveGState(context)
            path.addClip()
            CGContextDrawLinearGradient(context, gradient, CGPointMake(frame.width / 2, 0), CGPointMake(frame.width / 2, frame.height), CGGradientDrawingOptions())
            CGContextRestoreGState(context)
        }
    
        override func layoutSubviews() {
    
            // Ensure view has a transparent background color (not required)
            backgroundColor = UIColor.clearColor()
        }
    
    }
    

    用法

    gradientView.colors = [UIColor.blackColor().colorWithAlphaComponent(0.8), UIColor.clearColor()]


    结果

    【讨论】:

    • 你没有打电话给super.drawRect()有什么特别的原因吗?
    • @Bearwithme 没有。添加super.drawRect() 应该可以正常工作。
    • 最好添加到 GradientView.swift 的顶部:@IBInspectable var topColor: UIColor = UIColor.lightGrayColor()@IBInspectable var bottomColor: UIColor = UIColor.blueColor() 然后你可以在设置中看到Attribute Editor
    【解决方案7】:

    Xcode 11 • Swift 5.1


    您可以按如下方式设计自己的渐变视图:

    @IBDesignable
    public class Gradient: UIView {
        @IBInspectable var startColor:   UIColor = .black { didSet { updateColors() }}
        @IBInspectable var endColor:     UIColor = .white { didSet { updateColors() }}
        @IBInspectable var startLocation: Double =   0.05 { didSet { updateLocations() }}
        @IBInspectable var endLocation:   Double =   0.95 { didSet { updateLocations() }}
        @IBInspectable var horizontalMode:  Bool =  false { didSet { updatePoints() }}
        @IBInspectable var diagonalMode:    Bool =  false { didSet { updatePoints() }}
    
        override public class var layerClass: AnyClass { CAGradientLayer.self }
    
        var gradientLayer: CAGradientLayer { layer as! CAGradientLayer }
    
        func updatePoints() {
            if horizontalMode {
                gradientLayer.startPoint = diagonalMode ? .init(x: 1, y: 0) : .init(x: 0, y: 0.5)
                gradientLayer.endPoint   = diagonalMode ? .init(x: 0, y: 1) : .init(x: 1, y: 0.5)
            } else {
                gradientLayer.startPoint = diagonalMode ? .init(x: 0, y: 0) : .init(x: 0.5, y: 0)
                gradientLayer.endPoint   = diagonalMode ? .init(x: 1, y: 1) : .init(x: 0.5, y: 1)
            }
        }
        func updateLocations() {
            gradientLayer.locations = [startLocation as NSNumber, endLocation as NSNumber]
        }
        func updateColors() {
            gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
        }
        override public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
            super.traitCollectionDidChange(previousTraitCollection)
            updatePoints()
            updateLocations()
            updateColors()
        }
    
    }
    

    【讨论】:

    • 别忘了导入 UIKit
    • 能否解释一下这一行: override class var layerClass: AnyClass { return CAGradientLayer.self }
    • 最多可以使用多少个位置/位置/梯度站?似乎超过一定数量,iOS 没有渲染渐变。页面为空
    • 这是一个简单而好方法,你的努力。谢谢,+1
    【解决方案8】:

    更简洁的代码,可让您将任何 UIColor 传递给 GradientLayer 类的实例:

    class GradientLayer {
    
        let gradientLayer: CAGradientLayer
        let colorTop: CGColor
        let colorBottom: CGColor
    
        init(colorTop: UIColor, colorBottom: UIColor) {
            self.colorTop = colorTop.CGColor
            self.colorBottom = colorBottom.CGColor
            gradientLayer = CAGradientLayer()
            gradientLayer.colors = [colorTop, colorBottom]
            gradientLayer.locations = [0.0, 1.0]
        }
    }
    

    【讨论】:

      【解决方案9】:

      只是修改上面提到的答案。

      func setGradientBackground() {
          let colorTop =  UIColor(red: 255.0/255.0, green: 149.0/255.0, blue: 0.0/255.0, alpha: 1.0).cgColor
          let colorBottom = UIColor(red: 255.0/255.0, green: 94.0/255.0, blue: 58.0/255.0, alpha: 1.0).cgColor
                      
          let gradientLayer = CAGradientLayer()
          gradientLayer.colors = [colorTop, colorBottom]
          gradientLayer.locations = [0.0, 1.0]
          gradientLayer.frame = self.view.bounds
                  
          self.view.layer.insertSublayer(gradientLayer, at:0)
      }
      

      然后在viewWillAppear内调用这个方法

      override func viewWillAppear(_ animated: Bool) {
          setGradientBackground()
          super.viewWillAppear(animated)
      }
      

      【讨论】:

      • 这会在现有元素上放置一层,所以我什么都看不到。有什么建议吗?
      • self.view.layer.addSublayer(gradientLayer) 替换为self.view.layer.insertSublayer(gradientLayer, at: 0),这将使该层“低于”所有其他层
      • 有没有办法消除这种渐变效果?像删除功能?
      • 删除插入的子层
      • 有没有办法在某个层删除子层。喜欢0
      【解决方案10】:

      这是一个快速扩展,您可以在其中传递任意数量的任意颜色。它将在插入之前删除任何先前的渐变,如果需要,它将返回新插入的渐变层以进行进一步操作:

          extension UIView {
      
          /**
           Given an Array of CGColor, it will:
              - Remove all sublayers of type CAGradientLayer.
              - Create and insert a new CAGradientLayer.
      
           - Parameters: 
              - colors: An Array of CGColor with the colors for the gradient fill
      
           - Returns: The newly created gradient CAGradientLayer
           */
          func layerGradient(colors c:[CGColor])->CAGradientLayer {
              self.layer.sublayers = self.layer.sublayers?.filter(){!($0 is CAGradientLayer)}
              let layer : CAGradientLayer = CAGradientLayer()
              layer.frame.size = self.frame.size
              layer.frame.origin = CGPointZero
              layer.colors = c
              self.layer.insertSublayer(layer, atIndex: 0)
              return layer
          }
      }
      

      【讨论】:

        【解决方案11】:

        Swift 3 - 仅使用纹理和 SKSpriteNode,不需要 UIView

        import Foundation
        import SpriteKit
        
        class GradientSpriteNode : SKSpriteNode
        {
            convenience init(size: CGSize, colors: [UIColor], locations: [CGFloat])
            {
                let texture = GradientSpriteNode.texture(size: size, colors: colors, locations: locations)
                self.init(texture: texture, color:SKColor.clear, size: texture.size())
            }
        
            private override init(texture: SKTexture!, color: SKColor, size: CGSize) {
                super.init(texture: texture, color: color, size: size)
            }
        
            required init?(coder aDecoder: NSCoder) {
                fatalError("init(coder:) has not been implemented")
            }
        
            private static func texture(size: CGSize, colors: [UIColor], locations: [CGFloat]) -> SKTexture
            {
                UIGraphicsBeginImageContext(size)
                let context = UIGraphicsGetCurrentContext()!
                let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors.map{$0.cgColor} as CFArray, locations: locations)!
                context.drawLinearGradient(gradient, start: CGPoint(x: size.width / 2, y: 0), end: CGPoint(x: size.width / 2, y: size.height), options: CGGradientDrawingOptions())
                let image = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return SKTexture(image: image!)
        
            }
        }
        

        用法:

        let gradient = GradientSpriteNode(
                size: CGSize(width: 100, height: 100),
                colors: [UIColor.red, UIColor.blue],
                locations: [0.0, 1.0])
        addChild(gradient)
        

        【讨论】:

        • spritekitnode 与 cagradientlayer 的性能如何?必须渲染图像似乎会更慢。
        • 我不知道,但通常 ca** 类比 sprite kit 类的性能要好得多。
        【解决方案12】:

        此代码适用于 Swift 3.0

        class GradientView: UIView {
        
            override open class var layerClass: AnyClass {
                get{
                    return CAGradientLayer.classForCoder()
                }
            }
        
            required init?(coder aDecoder: NSCoder) {
                super.init(coder: aDecoder)
                let gradientLayer = self.layer as! CAGradientLayer
                let color1 = UIColor.white.withAlphaComponent(0.1).cgColor as CGColor
                let color2 = UIColor.white.withAlphaComponent(0.9).cgColor as CGColor
                gradientLayer.locations = [0.60, 1.0]
                gradientLayer.colors = [color2, color1]
            }
        }
        

        【讨论】:

        • @Blahji 你能分享一下使用的例子吗?并与 UILabel 一起使用
        • 向 UILabel 插入子层会隐藏文本,因此获得所需内容的最佳方法是将标签和渐变层添加到 UIView。
        【解决方案13】:

        只需指定要显示渐变颜色的视图框架。

        let firstColor =  UIColor(red: 69/255, green: 90/255, blue: 195/255, alpha: 1.0).CGColor
        
         let secondColor = UIColor(red: 230/255, green: 44/255, blue: 75/255, alpha: 1.0).CGColor
        
            let gradientLayer = CAGradientLayer()
            gradientLayer.colors = [ firstColor, secondColor]
            gradientLayer.locations = [ 0.0, 1.0]
            gradientLayer.frame = CGRectMake(0, 0, 375, 64)// You can mention frame here
        
            self.view.layer.addSublayer(gradientLayer)
        

        【讨论】:

          【解决方案14】:

          我有这些扩展:

          @IBDesignable class GradientView: UIView {
              @IBInspectable var firstColor: UIColor = UIColor.red
              @IBInspectable var secondColor: UIColor = UIColor.green
          
              @IBInspectable var vertical: Bool = true
          
              lazy var gradientLayer: CAGradientLayer = {
                  let layer = CAGradientLayer()
                  layer.colors = [firstColor.cgColor, secondColor.cgColor]
                  layer.startPoint = CGPoint.zero
                  return layer
              }()
          
              //MARK: -
          
              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: -
          
              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)
              }
          }
          
          @IBDesignable class ThreeColorsGradientView: UIView {
              @IBInspectable var firstColor: UIColor = UIColor.red
              @IBInspectable var secondColor: UIColor = UIColor.green
              @IBInspectable var thirdColor: UIColor = UIColor.blue
          
              @IBInspectable var vertical: Bool = true {
                  didSet {
                      updateGradientDirection()
                  }
              }
          
              lazy var gradientLayer: CAGradientLayer = {
                  let layer = CAGradientLayer()
                  layer.colors = [firstColor.cgColor, secondColor.cgColor, thirdColor.cgColor]
                  layer.startPoint = CGPoint.zero
                  return layer
              }()
          
              //MARK: -
          
              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: -
          
              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)
              }
          }
          
          @IBDesignable class RadialGradientView: UIView {
          
              @IBInspectable var outsideColor: UIColor = UIColor.red
              @IBInspectable var insideColor: UIColor = UIColor.green
          
              override func awakeFromNib() {
                  super.awakeFromNib()
          
                  applyGradient()
              }
          
              func applyGradient() {
                  let colors = [insideColor.cgColor, outsideColor.cgColor] as CFArray
                  let endRadius = sqrt(pow(frame.width/2, 2) + pow(frame.height/2, 2))
                  let center = CGPoint(x: bounds.size.width / 2, y: bounds.size.height / 2)
                  let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: nil)
                  let context = UIGraphicsGetCurrentContext()
          
                  context?.drawRadialGradient(gradient!, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: endRadius, options: CGGradientDrawingOptions.drawsBeforeStartLocation)
              }
          
              override func draw(_ rect: CGRect) {
                  super.draw(rect)
          
                  #if TARGET_INTERFACE_BUILDER
                      applyGradient()
                  #endif
              }
          }
          

          用法:

          【讨论】:

          • 最好不要在drawRect中添加图层,只是在设置时
          • 将此添加到我的 VC 视图中会阻止所有内容。所有元素都隐藏在渐变之下。怎么回事
          • self.layer.addSublayer(layer) 更改为self.layer.insertSublayer(layer, at: 0) 似乎可以防止渐变混淆界面构建器中的所有内容(至少在我的一次测试中)
          【解决方案15】:

          如果您有视图集合(多视图),请执行此操作

            func setGradientBackground() {
              let v:UIView
              for v in viewgradian
              //here viewgradian is your view Collection Outlet name
              {
                  let layer:CALayer
                  var arr = [AnyObject]()
                  for layer in v.layer.sublayers!
                  {
                     arr.append(layer)
                  }
          
                  let colorTop = UIColor(red: 216.0/255.0, green: 240.0/255.0, blue: 244.0/255.0, alpha: 1.0).cgColor
                  let colorBottom = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0).cgColor
                  let gradientLayer = CAGradientLayer()
                  gradientLayer.colors = [ colorBottom, colorTop]
                  gradientLayer.startPoint = CGPoint(x: 1.0, y: 0.0)
                  gradientLayer.endPoint = CGPoint(x: 0.0, y: 1.0)
                  gradientLayer.frame = v.bounds
                  v.layer.insertSublayer(gradientLayer, at: 0)
              }
          }
          

          【讨论】:

            【解决方案16】:

            这是在可重用的 Util 类文件中进行设置的一种变体

            在您的 Xcode 项目中:

            1. 创建一个名为 UI_Util.swift 的新 Swift 类,并按如下方式填充它:

              import Foundation
              import UIKit
              
              class UI_Util {
              
                  static func setGradientGreenBlue(uiView: UIView) {
              
                      let colorTop =  UIColor(red: 15.0/255.0, green: 118.0/255.0, blue: 128.0/255.0, alpha: 1.0).cgColor
                      let colorBottom = UIColor(red: 84.0/255.0, green: 187.0/255.0, blue: 187.0/255.0, alpha: 1.0).cgColor
              
                      let gradientLayer = CAGradientLayer()
                      gradientLayer.colors = [ colorTop, colorBottom]
                      gradientLayer.locations = [ 0.0, 1.0]
                      gradientLayer.frame = uiView.bounds
              
                      uiView.layer.insertSublayer(gradientLayer, at: 0)
                  }
              }
              

            1. 现在您可以像这样从任何 ViewController 调用该函数:

              class AbcViewController: UIViewController {
              
                  override func viewDidLoad() {
                      super.viewDidLoad()                
                      UI_Util.setGradientGreen(uiView: self.view)
                  }                
              

            感谢 katwal-Dipak 对函数代码的回答

            【讨论】:

              【解决方案17】:

              在 swift 3 上易于使用的扩展

              extension CALayer {
                  func addGradienBorder(colors:[UIColor] = [UIColor.red,UIColor.blue], width:CGFloat = 1) {
                      let gradientLayer = CAGradientLayer()
                      gradientLayer.frame =  CGRect(origin: .zero, size: self.bounds.size)
                      gradientLayer.startPoint = CGPoint(x:0.0, y:0.5)
                      gradientLayer.endPoint = CGPoint(x:1.0, y:0.5)
                      gradientLayer.colors = colors.map({$0.cgColor})
              
                      let shapeLayer = CAShapeLayer()
                      shapeLayer.lineWidth = width
                      shapeLayer.path = UIBezierPath(rect: self.bounds).cgPath
                      shapeLayer.fillColor = nil
                      shapeLayer.strokeColor = UIColor.black.cgColor
                      gradientLayer.mask = shapeLayer
              
                      self.addSublayer(gradientLayer)
                  }
              }
              

              使用你的观点,例如

              yourView.addGradienBorder(color: UIColor.black, opacity: 0.1, offset: CGSize(width:2 , height: 5), radius: 3, viewCornerRadius: 3.0)
              

              【讨论】:

                【解决方案18】:

                试试这个,它对我有用,

                  var gradientView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 35))
                  let gradientLayer:CAGradientLayer = CAGradientLayer()
                  gradientLayer.frame.size = self.gradientView.frame.size
                  gradientLayer.colors = 
                  [UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor] 
                  //Use diffrent colors
                  gradientView.layer.addSublayer(gradientLayer)
                

                您可以添加渐变颜色的起点和终点。

                    gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
                    gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
                

                更多详细介绍请参考Best Answer 或关注CAGradientLayer From Apple

                希望这对某些人有所帮助。

                【讨论】:

                • 使用startPointendPoint从左到右渐变:gradient.startPoint = CGPoint(x: 0.0, y: 0.5) gradient.endPoint = CGPoint(x: 1.0, y: 0.5)和从上到下:gradient.startPoint = CGPoint(x: 0.5, y: 0.0) gradient.endPoint = CGPoint(x: 0.5, y: 1.0)
                【解决方案19】:

                快速将 CAGradientLayer 应用于任何对象(水平和垂直)

                func makeGradientColor(`for` object : AnyObject , startPoint : CGPoint , endPoint : CGPoint) -> CAGradientLayer {
                    let gradient: CAGradientLayer = CAGradientLayer()
                
                    gradient.colors = [(UIColor(red: 59.0/255.0, green: 187.0/255.0, blue: 182.0/255.0, alpha: 1.00).cgColor), (UIColor(red: 57.0/255.0, green: 174.0/255.0, blue: 236.0/255.0, alpha: 1.00).cgColor)]
                    gradient.locations = [0.0 , 1.0]
                
                    gradient.startPoint = startPoint
                    gradient.endPoint = endPoint
                    gradient.frame = CGRect(x: 0.0, y: 0.0, width: object.frame.size.width, height: object.frame.size.height)
                    return gradient
                }
                

                如何使用

                let start : CGPoint = CGPoint(x: 0.0, y: 1.0)
                let end : CGPoint = CGPoint(x: 1.0, y: 1.0)
                let gradient: CAGradientLayer = self.makeGradientColor(for: vwTop, startPoint: start, endPoint: end)
                vwTop.layer.insertSublayer(gradient, at: 0)
                
                let start1 : CGPoint = CGPoint(x: 1.0, y: 1.0)
                let end1 : CGPoint = CGPoint(x: 1.0, y: 0.0)
                let gradient1: CAGradientLayer = self.makeGradientColor(for: vwTop, startPoint: start1, endPoint: end1)
                vwBottom.layer.insertSublayer(gradient1, at: 0)
                

                You can check output here

                【讨论】:

                  【解决方案20】:

                  我想为视图添加渐变,然后使用自动布局锚定它。

                      class GradientView: UIView {
                  
                      private let gradient: CAGradientLayer = {
                          let layer = CAGradientLayer()
                          let topColor: UIColor = UIColor(red:0.98, green:0.96, blue:0.93, alpha:0.5)
                          let bottomColor: UIColor = UIColor.white
                          layer.colors = [topColor.cgColor, bottomColor.cgColor]
                          layer.locations = [0,1]
                          return layer
                      }()
                  
                      init() {
                          super.init(frame: .zero)
                          gradient.frame = frame
                          layer.insertSublayer(gradient, at: 0)
                      }
                  
                      required init?(coder aDecoder: NSCoder) {
                          fatalError("init(coder:) has not been implemented")
                      }
                  
                      override func layoutSubviews() {
                          super.layoutSubviews()
                          gradient.frame = bounds
                  
                      }
                  }
                  

                  【讨论】:

                    【解决方案21】:

                    斯威夫特 4

                    添加视图插座

                    @IBOutlet weak var gradientView: UIView!

                    为视图添加渐变

                    func setGradient() {
                        let gradient: CAGradientLayer = CAGradientLayer()
                        gradient.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
                        gradient.locations = [0.0 , 1.0]
                        gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
                        gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
                        gradient.frame = gradientView.layer.frame
                        gradientView.layer.insertSublayer(gradient, at: 0)
                    }
                    

                    【讨论】:

                    • 如果 gradientView.layer.frame 不在 (0,0) 处,渐变层被置换。我会推荐使用 gradientView.layer.bounds 。
                    【解决方案22】:

                    有一个名为 Chameleon (https://github.com/viccalexander/Chameleon) 的库,可用于渐变颜色。它甚至可以实现渐变样式。这就是你如何在 swift 4 podfile 中添加它 pod 'ChameleonFramework/Swift', :git => 'https://github.com/ViccAlexander/Chameleon.git', :branch => 'wip/swift4'

                    import ChameleonFramework
                    
                    let colors:[UIColor] = [
                      UIColor.flatPurpleColorDark(), 
                      UIColor.flatWhiteColor()
                    ]
                    view.backgroundColor = GradientColor(.TopToBottom, frame: view.frame, colors: colors)
                    

                    【讨论】:

                      【解决方案23】:

                      使用下面的代码:

                      extension UIView {
                      func applyGradient(colours: [UIColor]) -> Void {
                       let gradient: CAGradientLayer = CAGradientLayer()
                       gradient.frame = self.bounds
                       gradient.colors = colours.map { $0.cgColor }
                       gradient.startPoint = CGPoint(x : 0.0, y : 0.5)
                       gradient.endPoint = CGPoint(x :1.0, y: 0.5)
                       self.layer.insertSublayer(gradient, at: 0)
                       }
                      }
                      

                      像这样调用这个函数:

                        self.mainView.applyGradient(colours: [.green, .blue])
                      

                      【讨论】:

                        【解决方案24】:

                        很简单

                            // MARK: - Gradient
                        extension CAGradientLayer {
                            enum Point {
                                case topLeft
                                case centerLeft
                                case bottomLeft
                                case topCenter
                                case center
                                case bottomCenter
                                case topRight
                                case centerRight
                                case bottomRight
                                var point: CGPoint {
                                    switch self {
                                    case .topLeft:
                                        return CGPoint(x: 0, y: 0)
                                    case .centerLeft:
                                        return CGPoint(x: 0, y: 0.5)
                                    case .bottomLeft:
                                        return CGPoint(x: 0, y: 1.0)
                                    case .topCenter:
                                        return CGPoint(x: 0.5, y: 0)
                                    case .center:
                                        return CGPoint(x: 0.5, y: 0.5)
                                    case .bottomCenter:
                                        return CGPoint(x: 0.5, y: 1.0)
                                    case .topRight:
                                        return CGPoint(x: 1.0, y: 0.0)
                                    case .centerRight:
                                        return CGPoint(x: 1.0, y: 0.5)
                                    case .bottomRight:
                                        return CGPoint(x: 1.0, y: 1.0)
                                    }
                                }
                            }
                            convenience init(start: Point, end: Point, colors: [CGColor], type: CAGradientLayerType) {
                                self.init()
                                self.startPoint = start.point
                                self.endPoint = end.point
                                self.colors = colors
                                self.locations = (0..<colors.count).map(NSNumber.init)
                                self.type = type
                            }
                        }
                        

                        这样使用:-

                        let fistColor = UIColor.white
                        let lastColor = UIColor.black
                        let gradient = CAGradientLayer(start: .topLeft, end: .topRight, colors: [fistColor.cgColor, lastColor.cgColor], type: .radial)
                        gradient.frame = yourView.bounds
                        yourView.layer.addSublayer(gradient)
                        

                        【讨论】:

                        • 为枚举点投票
                        【解决方案25】:

                        要将渐变添加到图层中,请添加:

                        let layer = CAGradientLayer()
                        layer.frame = CGRect(x: 64, y: 64, width: 120, height: 120)
                        layer.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
                        view.layer.addSublayer(layer)
                        

                        【讨论】:

                        • 请添加一些解释。
                        【解决方案26】:

                        对于那些想要答案的 Objective C 版本的人。在 iOS13 上测试并运行

                        // Done here so that constraints have completed and the frame is correct.
                        - (void) viewDidLayoutSubviews { 
                            [super viewDidLayoutSubviews];
                            UIColor *colorTop = [UIColor colorWithRed:(CGFloat)192.0/255.0 green: 38.0/255.0 blue: 42.0/255.0 alpha:1.0];
                            UIColor *colorBottom = [UIColor colorWithRed: 35.0/255.0 green: 2.0/255.0 blue: 2.0/255.0 alpha: 1.0];
                            CAGradientLayer *gl = [CAGradientLayer new];
                            [gl setColors:@[(id)[colorTop CGColor], (id)[colorBottom CGColor]]];
                            [gl setLocations:@[@0.0f, @1.0f]];
                            self.view.backgroundColor = [UIColor clearColor];
                            CALayer *backgroundLayer = gl;
                            backgroundLayer.frame = self.view.frame;
                            [self.view.layer insertSublayer:backgroundLayer atIndex:0];
                        }
                        

                        【讨论】:

                          【解决方案27】:

                          我注意到的一件事是你不能在不清除文本的情况下向 UILabel 添加渐变。一种简单的解决方法是使用 UIButton 并禁用用户交互。

                          【讨论】:

                            【解决方案28】:

                            SwiftUI:您可以使用LinearGradient 结构作为ZStack 中的第一个元素。作为ZStack 的“底部”,它将作为背景颜色。 AngularGradientRadialGradient 也可用。

                            import SwiftUI
                            
                            struct ContentView: View {
                                var body: some View {
                                    ZStack {
                                        LinearGradient(gradient: Gradient(colors: [.red, .blue]), startPoint: .top, endPoint: .bottom)
                                            .edgesIgnoringSafeArea(.all)
                                        // Put other content here; it will appear on top of the background gradient
                                    }
                                }
                            }
                            

                            【讨论】:

                              【解决方案29】:

                              我混合了Rohit SisodiaMGM 的答案

                              // MARK: - Gradient
                              
                              public enum CAGradientPoint {
                                  case topLeft
                                  case centerLeft
                                  case bottomLeft
                                  case topCenter
                                  case center
                                  case bottomCenter
                                  case topRight
                                  case centerRight
                                  case bottomRight
                                  var point: CGPoint {
                                      switch self {
                                      case .topLeft:
                                          return CGPoint(x: 0, y: 0)
                                      case .centerLeft:
                                          return CGPoint(x: 0, y: 0.5)
                                      case .bottomLeft:
                                          return CGPoint(x: 0, y: 1.0)
                                      case .topCenter:
                                          return CGPoint(x: 0.5, y: 0)
                                      case .center:
                                          return CGPoint(x: 0.5, y: 0.5)
                                      case .bottomCenter:
                                          return CGPoint(x: 0.5, y: 1.0)
                                      case .topRight:
                                          return CGPoint(x: 1.0, y: 0.0)
                                      case .centerRight:
                                          return CGPoint(x: 1.0, y: 0.5)
                                      case .bottomRight:
                                          return CGPoint(x: 1.0, y: 1.0)
                                      }
                                  }
                              }
                              
                              extension CAGradientLayer {
                              
                                  convenience init(start: CAGradientPoint, end: CAGradientPoint, colors: [CGColor], type: CAGradientLayerType) {
                                      self.init()
                                      self.frame.origin = CGPoint.zero
                                      self.startPoint = start.point
                                      self.endPoint = end.point
                                      self.colors = colors
                                      self.locations = (0..<colors.count).map(NSNumber.init)
                                      self.type = type
                                  }
                              }
                              
                              extension UIView {
                              
                                  func layerGradient(startPoint:CAGradientPoint, endPoint:CAGradientPoint ,colorArray:[CGColor], type:CAGradientLayerType ) {
                                      let gradient = CAGradientLayer(start: .topLeft, end: .topRight, colors: colorArray, type: type)
                                      gradient.frame.size = self.frame.size
                                      self.layer.insertSublayer(gradient, at: 0)
                                  }
                              }
                              

                              使用写:-

                                      btnUrdu.layer.cornerRadius = 25
                                      btnUrdu.layer.masksToBounds = true 
                                      btnUrdu.layerGradient(startPoint: .centerRight, endPoint: .centerLeft, colorArray: [UIColor.appBlue.cgColor, UIColor.appLightBlue.cgColor], type: .axial)
                              

                              输出:

                              【讨论】:

                                【解决方案30】:

                                Xcode 11 |斯威夫特 5

                                如果有人正在寻找一种快速简便的方法来为视图添加渐变:

                                extension UIView {
                                    
                                    func addGradient(colors: [UIColor] = [.blue, .white], locations: [NSNumber] = [0, 2], startPoint: CGPoint = CGPoint(x: 0.0, y: 1.0), endPoint: CGPoint = CGPoint(x: 1.0, y: 1.0), type: CAGradientLayerType = .axial){
                                        
                                        let gradient = CAGradientLayer()
                                        
                                        gradient.frame.size = self.frame.size
                                        gradient.frame.origin = CGPoint(x: 0.0, y: 0.0)
                                
                                        // Iterates through the colors array and casts the individual elements to cgColor
                                        // Alternatively, one could use a CGColor Array in the first place or do this cast in a for-loop
                                        gradient.colors = colors.map{ $0.cgColor }
                                        
                                        gradient.locations = locations
                                        gradient.startPoint = startPoint
                                        gradient.endPoint = endPoint
                                        
                                        // Insert the new layer at the bottom-most position
                                        // This way we won't cover any other elements
                                        self.layer.insertSublayer(gradient, at: 0)
                                    }
                                }
                                



                                扩展使用示例:

                                // Testing
                                view.addGradient()
                                        
                                // Two Colors
                                view.addGradient(colors: [.init(rgb: 0x75BBDB), .black], locations: [0, 3])
                                        
                                // Full Blown
                                view.addGradient(colors: [.init(rgb: 0x75BBDB), .black], locations: [0, 3], startPoint: CGPoint(x: 0.0, y: 1.5), endPoint: CGPoint(x: 1.0, y: 2.0), type: .axial)
                                



                                可选地,使用以下输入十六进制数字.init(rgb: 0x75BBDB)

                                extension UIColor {
                                   convenience init(red: Int, green: Int, blue: Int) {
                                       self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
                                   }
                                
                                   convenience init(rgb: Int) {
                                       self.init(
                                           red: (rgb >> 16) & 0xFF,
                                           green: (rgb >> 8) & 0xFF,
                                           blue: rgb & 0xFF
                                       )
                                   }
                                }
                                

                                【讨论】:

                                • 任何有任何圆角半径的人都会受益于:gradient.cornerRadius = self.layer.cornerRadius - 请注意不要在渐变之后应用圆角半径。
                                猜你喜欢
                                • 2020-04-21
                                • 1970-01-01
                                • 1970-01-01
                                • 2022-09-29
                                • 2022-10-14
                                • 1970-01-01
                                • 2016-12-13
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多