Как применить градиент к фоновому виду приложения iOS Swift
Я пытаюсь применить градиент в качестве цвета фона вида (главный вид раскадровки). Код запускается, но ничего не меняется. Я использую 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)
}
}
}
21 ответов:
цвета, которые вы предоставляете градиенту, должны быть типа
CGColor. Так что установите свой массивCGColortogl.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] } }
Xcode 8.2 * Swift 3.0.2
вы можете создать свой собственный вид градиента следующим образом:
@IBDesignable class GradientView: 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 class var layerClass: AnyClass { return CAGradientLayer.self } var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer } func updatePoints() { if horizontalMode { gradientLayer.startPoint = diagonalMode ? CGPoint(x: 1, y: 0) : CGPoint(x: 0, y: 0.5) gradientLayer.endPoint = diagonalMode ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0.5) } else { gradientLayer.startPoint = diagonalMode ? CGPoint(x: 0, y: 0) : CGPoint(x: 0.5, y: 0) gradientLayer.endPoint = diagonalMode ? CGPoint(x: 1, y: 1) : CGPoint(x: 0.5, y: 1) } } func updateLocations() { gradientLayer.locations = [startLocation as NSNumber, endLocation as NSNumber] } func updateColors() { gradientLayer.colors = [startColor.cgColor, endColor.cgColor] } override func layoutSubviews() { super.layoutSubviews() updatePoints() updateLocations() updateColors() } }
и если вам нужно изменить направление градиента, вы должны использовать 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, atIndex: 0)
просто изменив выше упомянутый ответ.
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) }
In 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) }
Я сделал расширение 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) } }
У меня есть эти расширения:
@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 } }использование:
попробуйте это , это работает для меня,
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)более подробное описание см. Лучший Ответ или вы можете следовать CAGradientLayer От Apple
надеется, что это помощь для кого-то.
расширения
UIViewС этим пользовательским классом.
GradientView.Свифт
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()]
результат
этот код будет работать с 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] } }
если вы хотите использовать 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] } }после этого в контроллере вида, в разделе class создайте экземпляр вашего класса "Color" следующим образом:
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. : D
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{.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)
для swift применить 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)
вот быстрое расширение, где вы можете пройти любое количество произвольных цветов. Он удалит все предыдущие градиенты перед вставкой одного и вернет вновь вставленный градиентный слой для дальнейших манипуляций, если это необходимо:
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(){!( 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 } }
просто укажите рамку вида, где вы хотите показать цвет градиента.
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)
более чистый код, который позволяет передавать любые
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] } }
вот вариант для настройки этого в многоразовом файле класса Util
в вашем проекте Xcode:
создайте новый класс Swift, назовите его UI_Util.Свифт, и заполнить его следующим образом:
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) } }
теперь вы можете вызвать функцию из любого ViewController следующим образом:
class AbcViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() UI_Util.setGradientGreen(uiView: self.view) }благодаря ответу katwal-Dipak для кода функции
простое в использовании расширение на 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({.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)
Если у вас есть коллекция представлений (несколько представлений), сделайте это
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) } }
Я хотел добавить градиент к виду, а затем закрепить его с помощью автоматической компоновки.
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 } }
Swift 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) }









Comments