我试图在运行时生成一个渐变颜色背景(纯色到透明)的视图。有办法做到吗?
当前回答
在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)
}
}
其他回答
因为我只需要一种类型的梯度在我的应用程序,我创建了一个子类的UIView和预配置梯度层初始化固定的颜色。 UIView的初始化器调用configuregradientlayer -方法,它配置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
这是我推荐的方法。
为了提高可重用性,我建议创建一个CAGradientLayer类别,并添加所需的渐变作为类方法。在头文件中像这样指定它们:
#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或任何其他所需的子类,并像这样使用它:
CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
backgroundLayer.frame = self.view.frame;
[self.view.layer insertSublayer:backgroundLayer atIndex:0];
快速的方法
This answer builds on the answers above and provides implementation for dealing with the problem of the gradient not being properly applied during rotation. It satisfies this problem by changing the gradient layer to a square so that rotation in all directions results in a correct gradient. The function signature includes a Swift variadic argument that allows one to pass in as many CGColorRef's (CGColor) as needed (see sample usage). Also provided is an example as a Swift extension so that one can apply a gradient to any 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)
}
使用方法:
在viewDidLoad ...
override func viewDidLoad() {
super.viewDidLoad()
configureGradientBackground(UIColor.redColor().CGColor, UIColor.whiteColor().CGColor)
}
扩展的实现
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(或子类),所有的UIViews都有calayer。
斯威夫特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)
}
我已经在代码中实现了这一点。
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];
现在我可以在视图中看到渐变。
基于Yuchen版本的简单swift视图
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]
推荐文章
- 更改UITextField和UITextView光标/插入符颜色
- 'Project Name'是通过优化编译的——步进可能会表现得很奇怪;变量可能不可用
- 如何设置回退按钮文本在Swift
- 模拟器慢动作动画现在打开了吗?
- 如何为TableView创建NSIndexPath
- 滑动删除和“更多”按钮(就像iOS 7的邮件应用程序)
- 使UINavigationBar透明
- 如何改变推和弹出动画在一个基于导航的应用程序
- 删除/重置核心数据中的所有条目?
- setNeedsLayout vs. setNeedsUpdateConstraints和layoutIfNeeded vs. updateConstraintsIfNeeded
- 不区分大小写的比较
- 我怎么能得到一个uiimage的高度和宽度?
- 我如何模仿地图应用程序的底部表格?
- 改变导航栏后退按钮的颜色
- iOS应用程序“应用程序无法验证”只在一台设备上