Reputation: 17
i have in my figma this style: background: linear-gradient(155.98deg, #F5FEFF 0%, #C5F8FF 0%, rgba(106, 164, 189, 0.5) 47.57%, #0E8B9C 88.75%), #FFFFFF; i need to make my uiview as linear-gradient
Upvotes: 0
Views: 4884
Reputation: 437552
The basic idea is to configure a CAGradientLayer
with an array of colors
and locations
. If you want a diagonal gradient, specify a startPoint
and endPoint
, too.
But you need to decipher that Figma CSS. The first parameter to linear-gradient
is the angle. Linear gradients in iOS are not measured in angles, but rather with startPoint
and endPoint
, both of which are CGPoint
references where 0, 0
represents the upper left corner of the view and 1, 1
represents the lower right corner. Your angle of 155.98deg
suggests that you're looking for a “from upper left to lower right” gradient, which would be a startPoint
of 0, 0
and an endPoint
of 1, 1
. (The exact mapping between the angle and these CGPoint
values will vary based upon the aspect ratio of the view in question.)
The next parameter to linear-gradient
is an array of tuples of colors and location. Solid colors are represented in hex strings. Translucent colors are represented with integer rgb
values. So #F5FEFF 0%
is at location 0.0 and a color of 0xf5
for red, 0xfe
for green, and 0xff
for blue. You need to divide all those numbers by 0xff (or 255). (The Xcode color literal will do that conversion for you.) And the 0% at the end of the string is the relative location of this color in the gradient (where 0% is the start of the gradient and 100% is the end). This correlates nicely to the CAGradientLayer
property locations
(though the % numbers are represented as values between 0
and 1
).
The rgba(106, 164, 189, 0.5) 47.57%
is red, green, and blue values of 106, 164, and 189, respectively, (each divided by 255). The 0.5 is an alpha of 50%. And the 47.57 is the position (47.57% of the way along the gradient).
Anyway, to render this, define an array of colors, array of positions, and the start and end of the gradient:
@IBDesignable class GradientView: UIView {
override class var layerClass: AnyClass { CAGradientLayer.self }
var gradientLayer: CAGradientLayer { layer as! CAGradientLayer }
override init(frame: CGRect = .zero) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
configure()
}
func configure() {
gradientLayer.colors = [#colorLiteral(red: 0.9607843137, green: 0.9960784314, blue: 1, alpha: 1), #colorLiteral(red: 0.7725490196, green: 0.9725490196, blue: 1, alpha: 1), #colorLiteral(red: 0.4156862745, green: 0.6431372549, blue: 0.7411764706, alpha: 0.5), #colorLiteral(red: 0.05490196078, green: 0.5450980392, blue: 0.6117647059, alpha: 1)].map { $0.cgColor }
gradientLayer.locations = [0, 0, 0.4757, 0.8875]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)
}
}
If you want to see either the hex representation or integer representation of those colors, just double click on the color and tap on "Other" to see the RGB representations. E.g. I double clicked on the second color and I can see the #C5F8FF
value:
A couple of final observations:
Note, I didn't just add a CAGradientLayer
and set its frame. Instead, I created a view whose backing layer is a gradient. That way, if the view size changes because of constraints (or if you animate the size change), the size of the CAGradientLayer
changes dynamically, too.
I made it @IBDesignable
so I could see it in the storyboard. That’s not necessary, but is useful if using storyboards.
I wonder if your designer really meant to have both #F5FEFF
and #C5F8FF
at the 0% position. I suspect that was a mistake. (Figma makes it too easy to have multiple color data points in the gradient overlap with each other at either 0% or 100%.)
The CSS you've provided does not look syntactically correct. Notably, I don't know what to make of that #FFFFFF
floating at the end (and your gradient points don’t go all the way to 100%). But, I don't think I need to know your full intent here ... you can just update the CAGradientLayer
colors
and locations
arrays as you see fit. Just make sure they both have the same number of entries.
As you have noted, if you tap on the rightmost “Code” tab in the panel on the right in Figma, you can see an iOS code snippet. I would be wary of using that code, verbatim, in your app, because it (a) won’t use the UIView
subclass outlined above, breaking if the view changes size or is animated; and (b) it will tend to use hard-coded values whereas you generally want to use constraints to dictate the layouts within iOS. Use this code snippet for inspiration, suggestions of possible API, etc., but I would not be inclined to use that exact code. Like all auto-generated code snippets, Figma’s suggested iOS code is not ideal.
Upvotes: 2
Reputation: 2027
let layerGradient = CAGradientLayer()
layerGradient.colors = [hexStringToUIColor(hex: "yourhex").cgColor, hexStringToUIColor(hex: "yourhex").cgColor]
layerGradient.startPoint = CGPoint(x: 0, y: 0.5)
layerGradient.endPoint = CGPoint(x: 1, y: 0.5)
layerGradient.frame = CGRect(x: 0, y: 0, width: yourView.bounds.width, height: yourView.bounds.height)
self.yourView.layer.addSublayer(layerGradient)
Essentially you add a layer on top of your view which you then assign a start point and end point and provide colors to use.
This is the function used to convert hex strings to colors
func hexStringToUIColor (hex:String) -> UIColor {
var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if (cString.hasPrefix("#")) {
cString.remove(at: cString.startIndex)
}
if ((cString.count) != 6) {
return UIColor.gray
}
var rgbValue:UInt64 = 0
Scanner(string: cString).scanHexInt64(&rgbValue)
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}
Upvotes: 0