How to Apply Gradient to background view of iOS Swift App
The Colors you're providing to gradient must be of type CGColor
. So set your array of CGColor
to gl.colors
.
The correct code is :
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]
}
}
Programmatically create a UIView with color gradient
Objective-C:
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];
Swift:
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: use startPoint and endPoint to change direction of gradient.
If there are any other views added onto this UIView
(such as a UILabel
), you may want to consider setting the background color of those UIView
’s to [UIColor clearColor]
so the gradient view is presented instead of the background color for sub views. Using clearColor
has a slight performance hit.
background Gradient : linear left to right in objective C
You need to set the startPoint and endPoint property of your gradientLayer. They represent the start coordinates of your first color and the coordinates of the end of your last color.
They are both CGPoints and their x and y should have values between 0.0 et 1.0.
By default the startPoint has these coordinates (0.5, 0.0), while the endPoint has those (0.5, 1.0).
(0.0, 0.0) is the top left corner while (1.0, 1.0) is the bottom right corner
so try:
theViewGradient.startPoint = CGPointMake(0.0, 0.5);
theViewGradient.endPoint = CGPointMake(1.0, 0.5);
Swift: Background gradient for UIView
There were 2 problems:
I needed to set the start and end points to provide a gradient direction:
func setGradientBackground(colorTop: UIColor, colorBottom: UIColor) {
let gradientLayer = CAGradientLayer()
gradientLayer.colors = [colorBottom.cgColor, colorTop.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.locations = [0, 1]
gradientLayer.frame = bounds
layer.insertSublayer(gradientLayer, at: 0)
}And the second issue was that
CAGradientLayer
takes effect after the view is layed out. I solved that callingsetGradientBackground()
onviewDidAppear
:override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
separatorView.setGradientBackground(colorTop: .clear, colorBottom: Colors.darkGrey)
}
Is there a way to make gradient background color in the interface builder?
To draw a gradient, you will have to subclass and override the drawRect programmatically:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents
(colorSpace,
(const CGFloat[8]){1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f},
(const CGFloat[2]){0.0f,1.0f},
2);
CGContextDrawLinearGradient(context,
gradient,
CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMinY(self.bounds)),
CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)),
0);
CGColorSpaceRelease(colorSpace);
CGContextRestoreGState(context);
}
The easiest way, which keeps your cells in the interface builder, is probably to subclass a UIView to have it draw a gradient in its drawRect and place it in your cell behind the other subviews:
GradientView *gradientView = [[GradientView alloc] init];
gradientView.frame = cell.bounds;
[cell addSubview:gradientView];
[cell sendSubviewToBack:gradientView];
However, the best way to do it is probably not to use the interface builder for this and make a subclass of UITableViewCell. For advanced customization, interface builders tend to only make things more complicated in my experience. That's up to personal preference though.
Set Background Gradient on Button in Swift
Your code works fine. You just have to remember to set the gradient's frame every time. It is better to just make the gradient category also set the frame of the view for you.
That way you don't forget and it applies fine.
import UIKit
extension UIView {
func applyGradient(colours: [UIColor]) -> CAGradientLayer {
return self.applyGradient(colours: colours, locations: nil)
}
func applyGradient(colours: [UIColor], locations: [NSNumber]?) -> CAGradientLayer {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = colours.map { $0.cgColor }
gradient.locations = locations
self.layer.insertSublayer(gradient, at: 0)
return gradient
}
}
class ViewController: UIViewController {
@IBOutlet weak var btn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.btn.applyGradient(colours: [.yellow, .blue])
self.view.applyGradient(colours: [.yellow, .blue, .red], locations: [0.0, 0.5, 1.0])
}
}
Buttons are views. You apply gradients to it the same way you would apply it to any other view.
Picture Proof:
Video Proof:
https://i.imgur.com/ssDTqPu.mp4
Applying gradient background for UIView using auto layout
You can subclass the UIView and override drawRect method where you add your gradient.
Updated to Swift 4
class GradientView: UIView {
private let gradient : CAGradientLayer = CAGradientLayer()
private let gradientStartColor: UIColor
private let gradientEndColor: UIColor
init(gradientStartColor: UIColor, gradientEndColor: UIColor) {
self.gradientStartColor = gradientStartColor
self.gradientEndColor = gradientEndColor
super.init(frame: .zero)
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
gradient.frame = self.bounds
}
override public func draw(_ rect: CGRect) {
gradient.frame = self.bounds
gradient.colors = [gradientEndColor.cgColor, gradientStartColor.cgColor]
gradient.startPoint = CGPoint(x: 1, y: 0)
gradient.endPoint = CGPoint(x: 0.2, y: 1)
if gradient.superlayer == nil {
layer.insertSublayer(gradient, at: 0)
}
}
}
After you create your UIView you just need to add your constraints to that view.
Related Topics
Why Won't My Collection View Cells Display in the iPhone Simulator
How to Use Core Data Value from Picker? #Swiftui #Coredata
Var Declaration with Type VS Without
Finding All Types That Conform to a Protocol
Can't Append Value to My Nsarray Variable
Toggle Selectedrange Attributes in Uitextview
Enum Method Returning a Dynamic Type
How to Get Video Duration Fro Avasset in Swift
Array Search Function Not Working in Swift
How to Use Dispatchgroup/Gcd to Execute Functions Sequentially in Swift
Swift 2 Unrecognized Selector in Tapgesture
Swift Conforming Multiple Protocols Inherits from Same Protocol with Associated Type
Swift Uitableviewautomaticdimension Is Not Working
Value' Is Inaccessible Due to 'Internal' Protection Level
Parse.Com Pfquery Order by Time (Swift)
Make Swiftui Rectangle Same Height or Width as Another Rectangle