Reputation: 7591
If I have two UIColors, what's the best way to draw an even gradient between them over an arbitrarily-sized area?
I am guessing you would create a UIView subclass and use the CG drawing methods in the drawRect method. I just don't know which ones, or if there are any pitfalls to watch out for, like performance. Has anyone done this?
Upvotes: 11
Views: 26799
Reputation: 487
You can use the following to apply a gradient on the view
-(void)applyGradientEffecttoView:(UIView *)aView
{
// Create the colors
UIColor *darkOp = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0];
UIColor *lightOp =[UIColor colorWithRed:255.0f green:255.0f blue:255.0f alpha:0.0];
// Create the gradient
CAGradientLayer *gradient = [CAGradientLayer layer];
// Set colors
gradient.colors = [NSArray arrayWithObjects:
(id)lightOp.CGColor,
(id)darkOp.CGColor,
nil];
gradient.locations = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0f],
[NSNumber numberWithFloat:0.5],
nil];
// Set bounds
gradient.frame = aView.bounds;
// Add the gradient to the view
[aView.layer insertSublayer:gradient atIndex:0];
}
Upvotes: 0
Reputation: 2905
For views that draw text, such as UILabel
, UITextView
, and UITextField
, you should add the gradient inside the drawRect
function. (see this post for an example).
There are some great subclasses of UILabel
, UITextView
, and UITextField
that allow you to add a gradient pretty easily (see JBGradient on GitHub).
Upvotes: 0
Reputation: 3433
I found that using CAGradientLayer produced a gradient with noticeable stepping Ended up using this
As per this question Gradients on UIView and UILabels On iPhone
Upvotes: 0
Reputation: 3374
The Swift way to add Gradient is :
var view : UIView = UIView(frame: CGRectMake(0, 0, 320, 100))
var g : CAGradientLayer = CAGradientLayer()
g.frame = gradientView.bounds
g.colors = ["000000".UIColor.CGColor , "111111".UIColor.CGColor]
view.layer.insertSublayer(g, atIndex: 0)
UIColor()
is a helper class for Swift to convert hex color
to rgb color
, highly recommended.
Upvotes: 3
Reputation: 49693
Same-ish solution as @Anton Chikin but a little more robust. Notice the override of layerClass
... this way, you don't have to worry about setting the frame and the frame is automatically updated upon rotation & resize.
class GradientView: UIView {
var colorA : UIColor = UIColor.greenColor() {
didSet { updateGradient() }
}
var colorB : UIColor = UIColor.blueColor() {
didSet { updateGradient() }
}
override class func layerClass() -> AnyClass {
return CAGradientLayer.self
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
updateGradient()
}
func updateGradient() {
if let gLayer = layer as? CAGradientLayer {
gLayer.colors = [colorA.CGColor, colorB.CGColor]
}
}
}
If you're using IB, you can set the properties via "User Defined Runtime Attributes".
If you're not using IB, use the other initializer.
Upvotes: 0
Reputation: 1836
#import <QuartzCore/QuartzCore.h>
- (void) setGradient {
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.view.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor blackColor] CGColor], nil];
[self.view.layer insertSublayer:gradient atIndex:0];
}
Don't forget to add QuartzCore library to your project.
Upvotes: 50
Reputation: 85532
You'll want to use CGGradient. See the iPhone Dev Center "CGGradient Reference" document.
Upvotes: 20