我正在尝试在运行时生成具有渐变颜色背景(纯色到透明)的视图 . 有没有办法做到这一点?
您可以创建自定义类 GradientView :
GradientView
Swift 4, Swift 3
class GradientView: UIView { override open class var layerClass: AnyClass { return CAGradientLayer.classForCoder() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) let gradientLayer = layer as! CAGradientLayer gradientLayer.colors = [UIColor.white.cgColor, UIColor.black.cgColor] } }
在故事板中,将类类型设置为您想要具有渐变背景的任何视图:
这在以下方面更好:
无需设置 CLayer 的框架
CLayer
在 UIView 上照常使用 NSConstraint
UIView
NSConstraint
不需要创建子图层(减少内存使用)
我在swift中实现了这个扩展:
Swift 3
extension UIView { func addGradientWithColor(color: UIColor) { let gradient = CAGradientLayer() gradient.frame = self.bounds gradient.colors = [UIColor.clear.cgColor, color.cgColor] self.layer.insertSublayer(gradient, at: 0) } }
Swift 2.2
extension UIView { func addGradientWithColor(color: UIColor) { let gradient = CAGradientLayer() gradient.frame = self.bounds gradient.colors = [UIColor.clearColor().CGColor, color.CGColor] self.layer.insertSublayer(gradient, atIndex: 0) } }
不,我可以像这样在每个视图上设置渐变:
myImageView.addGradientWithColor(UIColor.blue)
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)]; CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = view.bounds; gradient.colors = @[(id)[UIColor whiteColor].CGColor, (id)[UIColor blackColor].CGColor]; [view.layer insertSublayer:gradient atIndex:0];
let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50)) let gradient = CAGradientLayer() gradient.frame = view.bounds gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor] view.layer.insertSublayer(gradient, at: 0)
Info :使用startPoint和endPoint到change direction of gradient .
如果在此 UIView 上添加了任何其他视图(例如 UILabel ),您可能需要考虑将 UIView 的背景颜色设置为 [UIColor clearColor] ,以便显示渐变视图而不是子视图的背景颜色 . 使用 clearColor 会有轻微的性能影响 .
UILabel
[UIColor clearColor]
clearColor
调用上面的解决方案来更新层是一个好主意
viewDidLayoutSubviews
正确更新视图
A Swift Approach
这个答案 Build 在上面的答案的基础上,并提供了处理旋转期间未正确应用的梯度问题的实现 . 它通过将渐变层更改为正方形来满足此问题,以便在所有方向上的旋转产生正确的渐变 . 函数签名包含一个Swift可变参数,允许根据需要传入尽可能多的CGColorRef(CGColor)(参见示例用法) . 还提供了作为Swift扩展的示例,以便可以将渐变应用于任何UIView .
func configureGradientBackground(colors:CGColorRef...){ let gradient: CAGradientLayer = CAGradientLayer() let maxWidth = max(self.view.bounds.size.height,self.view.bounds.size.width) let squareFrame = CGRect(origin: self.view.bounds.origin, size: CGSizeMake(maxWidth, maxWidth)) gradient.frame = squareFrame gradient.colors = colors view.layer.insertSublayer(gradient, atIndex: 0) }
To use:
在viewDidLoad中......
override func viewDidLoad() { super.viewDidLoad() configureGradientBackground(UIColor.redColor().CGColor, UIColor.whiteColor().CGColor) }
Extension implementation
extension CALayer { func configureGradientBackground(colors:CGColorRef...){ let gradient = CAGradientLayer() let maxWidth = max(self.bounds.size.height,self.bounds.size.width) let squareFrame = CGRect(origin: self.bounds.origin, size: CGSizeMake(maxWidth, maxWidth)) gradient.frame = squareFrame gradient.colors = colors self.insertSublayer(gradient, atIndex: 0) } }
扩展用例示例:
override func viewDidLoad() { super.viewDidLoad() self.view.layer.configureGradientBackground(UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor, UIColor.whiteColor().CGColor) }
这意味着渐变背景现在可以应用于任何UIControl,因为所有控件都是UIViews(或子类),并且所有UIView都有CALayers .
Swift 4
扩展实施
extension CALayer { public func configureGradientBackground(_ colors:CGColor...){ let gradient = CAGradientLayer() let maxWidth = max(self.bounds.size.height,self.bounds.size.width) let squareFrame = CGRect(origin: self.bounds.origin, size: CGSize(width: maxWidth, height: maxWidth)) gradient.frame = squareFrame gradient.colors = colors self.insertSublayer(gradient, at: 0) } }
override func viewDidLoad() { super.viewDidLoad() self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor) }
SWIFT 3
To add a gradient layer on your view
@IBOutlet var YOURVIEW : UIView!
var gradient = CAGradientLayer()
YOURVIEW.layoutIfNeeded()
gradient.startPoint = CGPoint(x: CGFloat(0), y: CGFloat(1)) gradient.endPoint = CGPoint(x: CGFloat(1), y: CGFloat(0)) gradient.frame = YOURVIEW.bounds gradient.colors = [UIColor.red.cgColor, UIColor.green.cgColor] gradient.colors = [ UIColor(red: 255.0/255.0, green: 56.0/255.0, blue: 224.0/255.0, alpha: 1.0).cgColor,UIColor(red: 86.0/255.0, green: 13.0/255.0, blue: 232.0/255.0, alpha: 1.0).cgColor,UIColor(red: 16.0/255.0, green: 173.0/255.0, blue: 245.0/255.0, alpha: 1.0).cgColor] gradient.locations = [0.0 ,0.6 ,1.0] YOURVIEW.layer.insertSublayer(gradient, at: 0)
你在找什么是 CAGradientLayer . 每个 UIView 都有一个图层 - 您可以在该图层中添加子图层,就像添加子视图一样 . 一个特定的类型是 CAGradientLayer ,您可以在其中为它们提供一系列颜色以进行渐变 .
CAGradientLayer
一个例子是这个简单的渐变视图包装器:
http://oleb.net/blog/2010/04/obgradientview-a-simple-uiview-wrapper-for-cagradientlayer/
请注意,您需要包含QuartZCore框架才能访问UIView的所有图层部分 .
由于我在整个应用程序中只需要一种渐变,因此我创建了一个UIView的子类,并在初始化时使用固定颜色预先配置了渐变层 . UIView的初始化程序调用configureGradientLayer-method,它配置CAGradientLayer:
DDGradientView.h:
#import <UIKit/UIKit.h> @interface DDGradientView : UIView { } @end
DDGradientView.m:
#import "DDGradientView.h" @implementation DDGradientView // Change the views layer class to CAGradientLayer class + (Class)layerClass { return [CAGradientLayer class]; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if(self) { [self configureGradientLayer]; } return self; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if(self) { [self configureGradientLayer]; } return self; } // Make custom configuration of your gradient here - (void)configureGradientLayer { CAGradientLayer *gLayer = (CAGradientLayer *)self.layer; gLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor lightGrayColor] CGColor], nil]; } @end
我使用Swift的扩展功能和枚举扩展了接受的答案 .
哦,如果你像我一样使用Storyboard,请务必在 viewDidLayoutSubviews() 或之后调用 gradientBackground(from:to:direction:) .
viewDidLayoutSubviews()
gradientBackground(from:to:direction:)
enum GradientDirection { case leftToRight case rightToLeft case topToBottom case bottomToTop } extension UIView { func gradientBackground(from color1: UIColor, to color2: UIColor, direction: GradientDirection) { let gradient = CAGradientLayer() gradient.frame = self.bounds gradient.colors = [color1.cgColor, color2.cgColor] switch direction { case .leftToRight: gradient.startPoint = CGPoint(x: 0.0, y: 0.5) gradient.endPoint = CGPoint(x: 1.0, y: 0.5) case .rightToLeft: gradient.startPoint = CGPoint(x: 1.0, y: 0.5) gradient.endPoint = CGPoint(x: 0.0, y: 0.5) case .bottomToTop: gradient.startPoint = CGPoint(x: 0.5, y: 1.0) gradient.endPoint = CGPoint(x: 0.5, y: 0.0) default: break } self.layer.insertSublayer(gradient, at: 0) } }
在Swift 3.1中,我已将此扩展添加到UIView
import Foundation import UIKit import CoreGraphics extension UIView { func gradientOfView(withColours: UIColor...) { var cgColours = [CGColor]() for colour in withColours { cgColours.append(colour.cgColor) } let grad = CAGradientLayer() grad.frame = self.bounds grad.colors = cgColours self.layer.insertSublayer(grad, at: 0) } }
然后我打电话给他
class OverviewVC: UIViewController { override func viewDidLoad() { super.viewDidLoad() self.view.gradientOfView(withColours: UIColor.red,UIColor.green, UIColor.blue) } }
Swift 4:
在IB中正确显示渐变:
@IBDesignable public class GradientView: UIView { override open class var layerClass: AnyClass { return CAGradientLayer.classForCoder() } required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) configureGradientLayer() } public override init(frame: CGRect) { super.init(frame: frame) configureGradientLayer() } func configureGradientLayer() { let gradientLayer = layer as! CAGradientLayer gradientLayer.colors = [UIColor(hex: 0x003399).cgColor, UIColor(hex: 0x00297b).cgColor] } }
To give gradient color to UIView (swift 4.2)
func makeGradientLayer(`for` object : UIView, startPoint : CGPoint, endPoint : CGPoint, gradientColors : [Any]) -> CAGradientLayer { let gradient: CAGradientLayer = CAGradientLayer() gradient.colors = gradientColors gradient.locations = [0.0 , 1.0] gradient.startPoint = startPoint gradient.endPoint = endPoint gradient.frame = CGRect(x: 0, y: 0, w: object.frame.size.width, h: object.frame.size.height) return gradient }
How to use
let start : CGPoint = CGPoint(x: 0.0, y: 1.0) let end : CGPoint = CGPoint(x: 1.0, y: 1.0) let gradient: CAGradientLayer = makeGradientLayer(for: cell, startPoint: start, endPoint: end, gradientColors: [ UIColor(red:0.92, green:0.07, blue:0.4, alpha:1).cgColor, UIColor(red:0.93, green:0.11, blue:0.14, alpha:1).cgColor ]) self.vwTemp.layer.insertSublayer(gradient, at: 0)
尝试这对我来说就像一个魅力,
Objective C
我已将 RGB 渐变背景颜色设置为 UIview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,35)]; CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = view.bounds; gradient.startPoint = CGPointZero; gradient.endPoint = CGPointMake(1, 1); gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:34.0/255.0 green:211/255.0 blue:198/255.0 alpha:1.0] CGColor],(id)[[UIColor colorWithRed:145/255.0 green:72.0/255.0 blue:203/255.0 alpha:1.0] CGColor], nil]; [view.layer addSublayer:gradient];
UPDATED :- Swift3 +
Code : -
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 Doc
希望这对某些人有所帮助 .
我的解决方案是创建 UIView 子类,其中 CAGradientLayer 可作为只读属性访问 . 这样您就可以根据需要自定义渐变,而不需要自己处理布局更改 . 子类实现:
@interface GradientView : UIView @property (nonatomic, readonly) CAGradientLayer *gradientLayer; @end @implementation GradientView + (Class)layerClass { return [CAGradientLayer class]; } - (CAGradientLayer *)gradientLayer { return (CAGradientLayer *)self.layer; } @end
用法:
self.iconBackground = [GradientView new]; [self.background addSubview:self.iconBackground]; self.iconBackground.gradientLayer.colors = @[(id)[UIColor blackColor].CGColor, (id)[UIColor whiteColor].CGColor]; self.iconBackground.gradientLayer.startPoint = CGPointMake(1.0f, 1.0f); self.iconBackground.gradientLayer.endPoint = CGPointMake(0.0f, 0.0f);
这是我推荐的方法 .
为了提高可重用性,我想创建一个 CAGradientLayer 的类别,并将所需的渐变添加为类方法 . 在 header 文件中指定它们,如下所示:
header
#import <QuartzCore/QuartzCore.h> @interface CAGradientLayer (SJSGradients) + (CAGradientLayer *)redGradientLayer; + (CAGradientLayer *)blueGradientLayer; + (CAGradientLayer *)turquoiseGradientLayer; + (CAGradientLayer *)flavescentGradientLayer; + (CAGradientLayer *)whiteGradientLayer; + (CAGradientLayer *)chocolateGradientLayer; + (CAGradientLayer *)tangerineGradientLayer; + (CAGradientLayer *)pastelBlueGradientLayer; + (CAGradientLayer *)yellowGradientLayer; + (CAGradientLayer *)purpleGradientLayer; + (CAGradientLayer *)greenGradientLayer; @end
然后在您的实现文件中,使用以下语法指定每个渐变:
+ (CAGradientLayer *)flavescentGradientLayer { UIColor *topColor = [UIColor colorWithRed:1 green:0.92 blue:0.56 alpha:1]; UIColor *bottomColor = [UIColor colorWithRed:0.18 green:0.18 blue:0.18 alpha:1]; NSArray *gradientColors = [NSArray arrayWithObjects:(id)topColor.CGColor, (id)bottomColor.CGColor, nil]; NSArray *gradientLocations = [NSArray arrayWithObjects:[NSNumber numberWithInt:0.0],[NSNumber numberWithInt:1.0], nil]; CAGradientLayer *gradientLayer = [CAGradientLayer layer]; gradientLayer.colors = gradientColors; gradientLayer.locations = gradientLocations; return gradientLayer; }
然后只需在 ViewController 或任何其他所需的 subclass 中导入此类别,并像这样使用它:
ViewController
subclass
CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer]; backgroundLayer.frame = self.view.frame; [self.view.layer insertSublayer:backgroundLayer atIndex:0];
extension UIView { func applyGradient(isTopBottom: Bool, colorArray: [UIColor]) { if let sublayers = layer.sublayers { let _ = sublayers.filter({ $0 is CAGradientLayer }).map({ $0.removeFromSuperlayer() }) } let gradientLayer = CAGradientLayer() gradientLayer.colors = colorArray.map({ $0.cgColor }) if isTopBottom { gradientLayer.locations = [0.0, 1.0] } else { //leftRight gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) } backgroundColor = .clear gradientLayer.frame = bounds layer.insertSublayer(gradientLayer, at: 0) } }
用法
someView.applyGradient(isTopBottom: true, colorArray: [.green, .blue])
我在我的代码中实现了这一点 .
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 31.0f)]; view1.backgroundColor = [UIColor clearColor]; CAGradientLayer *gradient = [CAGradientLayer layer]; gradient.frame = view1.bounds; UIColor *topColor = [UIColor colorWithRed:132.0/255.0 green:222.0/255.0 blue:109.0/255.0 alpha:1.0]; UIColor *bottomColor = [UIColor colorWithRed:31.0/255.0 green:150.0/255.0 blue:99.0/255.0 alpha:1.0]; gradient.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil]; [view1.layer insertSublayer:gradient atIndex:0];
现在我可以在视图上看到渐变 .
Swift Implementation:
var gradientLayerView: UIView = UIView(frame: CGRectMake(0, 0, view.bounds.width, 50)) var gradient: CAGradientLayer = CAGradientLayer() gradient.frame = gradientLayerView.bounds gradient.colors = [UIColor.grayColor().CGColor, UIColor.clearColor().CGColor] gradientLayerView.layer.insertSublayer(gradient, atIndex: 0) self.view.layer.insertSublayer(gradientLayerView.layer, atIndex: 0)
基于雨辰版本的简单快速视图
class GradientView: UIView { override class func layerClass() -> AnyClass { return CAGradientLayer.self } lazy var gradientLayer: CAGradientLayer = { return self.layer as! CAGradientLayer }() override init(frame: CGRect) { super.init(frame: frame) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } }
那么你可以像这样初始化后使用gradientLayer ...
someView.gradientLayer.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]
19 回答
您可以创建自定义类
GradientView
:Swift 4, Swift 3
在故事板中,将类类型设置为您想要具有渐变背景的任何视图:
这在以下方面更好:
无需设置
CLayer
的框架在
UIView
上照常使用NSConstraint
不需要创建子图层(减少内存使用)
我在swift中实现了这个扩展:
Swift 3
Swift 2.2
不,我可以像这样在每个视图上设置渐变:
Objective-C:
斯威夫特:
Info :使用startPoint和endPoint到change direction of gradient .
如果在此
UIView
上添加了任何其他视图(例如UILabel
),您可能需要考虑将UIView
的背景颜色设置为[UIColor clearColor]
,以便显示渐变视图而不是子视图的背景颜色 . 使用clearColor
会有轻微的性能影响 .调用上面的解决方案来更新层是一个好主意
正确更新视图
A Swift Approach
这个答案 Build 在上面的答案的基础上,并提供了处理旋转期间未正确应用的梯度问题的实现 . 它通过将渐变层更改为正方形来满足此问题,以便在所有方向上的旋转产生正确的渐变 . 函数签名包含一个Swift可变参数,允许根据需要传入尽可能多的CGColorRef(CGColor)(参见示例用法) . 还提供了作为Swift扩展的示例,以便可以将渐变应用于任何UIView .
To use:
在viewDidLoad中......
Extension implementation
扩展用例示例:
这意味着渐变背景现在可以应用于任何UIControl,因为所有控件都是UIViews(或子类),并且所有UIView都有CALayers .
Swift 4
扩展实施
扩展用例示例:
SWIFT 3
To add a gradient layer on your view
YOURVIEW.layoutIfNeeded()
gradient.startPoint = CGPoint(x: CGFloat(0), y: CGFloat(1)) gradient.endPoint = CGPoint(x: CGFloat(1), y: CGFloat(0)) gradient.frame = YOURVIEW.bounds gradient.colors = [UIColor.red.cgColor, UIColor.green.cgColor] gradient.colors = [ UIColor(red: 255.0/255.0, green: 56.0/255.0, blue: 224.0/255.0, alpha: 1.0).cgColor,UIColor(red: 86.0/255.0, green: 13.0/255.0, blue: 232.0/255.0, alpha: 1.0).cgColor,UIColor(red: 16.0/255.0, green: 173.0/255.0, blue: 245.0/255.0, alpha: 1.0).cgColor] gradient.locations = [0.0 ,0.6 ,1.0] YOURVIEW.layer.insertSublayer(gradient, at: 0)
你在找什么是
CAGradientLayer
. 每个UIView
都有一个图层 - 您可以在该图层中添加子图层,就像添加子视图一样 . 一个特定的类型是CAGradientLayer
,您可以在其中为它们提供一系列颜色以进行渐变 .一个例子是这个简单的渐变视图包装器:
http://oleb.net/blog/2010/04/obgradientview-a-simple-uiview-wrapper-for-cagradientlayer/
请注意,您需要包含QuartZCore框架才能访问UIView的所有图层部分 .
由于我在整个应用程序中只需要一种渐变,因此我创建了一个UIView的子类,并在初始化时使用固定颜色预先配置了渐变层 . UIView的初始化程序调用configureGradientLayer-method,它配置CAGradientLayer:
DDGradientView.h:
DDGradientView.m:
我使用Swift的扩展功能和枚举扩展了接受的答案 .
哦,如果你像我一样使用Storyboard,请务必在
viewDidLayoutSubviews()
或之后调用gradientBackground(from:to:direction:)
.Swift 3
在Swift 3.1中,我已将此扩展添加到UIView
然后我打电话给他
Swift 4:
在IB中正确显示渐变:
To give gradient color to UIView (swift 4.2)
How to use
尝试这对我来说就像一个魅力,
Objective C
我已将 RGB 渐变背景颜色设置为 UIview
UPDATED :- Swift3 +
Code : -
您可以添加渐变颜色的起点和终点 .
有关详细说明,请参阅CAGradientLayer Doc
希望这对某些人有所帮助 .
我的解决方案是创建
UIView
子类,其中CAGradientLayer
可作为只读属性访问 . 这样您就可以根据需要自定义渐变,而不需要自己处理布局更改 . 子类实现:用法:
这是我推荐的方法 .
为了提高可重用性,我想创建一个
CAGradientLayer
的类别,并将所需的渐变添加为类方法 . 在header
文件中指定它们,如下所示:然后在您的实现文件中,使用以下语法指定每个渐变:
然后只需在
ViewController
或任何其他所需的subclass
中导入此类别,并像这样使用它:用法
我在我的代码中实现了这一点 .
现在我可以在视图上看到渐变 .
Swift Implementation:
基于雨辰版本的简单快速视图
那么你可以像这样初始化后使用gradientLayer ...