How to Apply Gradient to background view of iOS Sw

2019-01-01 12:20发布

I'm trying to apply a gradient as the background color of a View (main view of a storyboard). The code runs, but nothing changes. I'm using xCode Beta 2 and Swift.

Here's the code:

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]
  }
}

then in the view controller:

  let colors = Colors()

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

22条回答
余生无你
2楼-- · 2019-01-01 12:40

Easy to use extension on 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)
    }
}

use to your view, example

yourView.addGradienBorder(color: UIColor.black, opacity: 0.1, offset: CGSize(width:2 , height: 5), radius: 3, viewCornerRadius: 3.0)
查看更多
与风俱净
3楼-- · 2019-01-01 12:43

This code will work with 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]
    }
}
查看更多
心情的温度
4楼-- · 2019-01-01 12:43

Swift 3 - Uses only textures and SKSpriteNode, doesn't require 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!)

    }
}

Usage:

let gradient = GradientSpriteNode(
        size: CGSize(width: 100, height: 100),
        colors: [UIColor.red, UIColor.blue],
        locations: [0.0, 1.0])
addChild(gradient)
查看更多
忆尘夕之涩
5楼-- · 2019-01-01 12:44

Here's a swift extension where you can pass any amount of arbitrary colors. It will remove any previous gradients before inserting one and it will return the newly inserted gradient layer for further manipulation if needed:

    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
    }
}
查看更多
不再属于我。
6楼-- · 2019-01-01 12:44

Here's a variation for setting this up in a reusable Util class file

In your Xcode project:

  1. Create a new Swift class call it UI_Util.swift, and populate it as follows:

    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. Now you can call the function from any ViewController like so:

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

Thanks to katwal-Dipak's answer for the function code

查看更多
只靠听说
7楼-- · 2019-01-01 12:45

And if you need to change the direction of the gradient you have to use startPoint and 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, atIndex: 0)
查看更多
登录 后发表回答