Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set a gradient border on UIView?

It's very easy to put a simple border on a UIView. You simply link to QuartzCore, import it, and use:

self.view.layer.borderColor = [UIColor redColor].CGColor;
self.view.layer.borderWidth = 2.0f;

My question is... Is there a way to make this border use a gradient. I know how to apply a gradient mask to the entire view, but not just to its border. I'm assuming this could involve a custom view and CoreGraphics drawing inside drawRect:, but I'm not sure where to start.

like image 804
shawnwall Avatar asked Apr 17 '12 23:04

shawnwall


1 Answers

I'm not entirely sure of what you mean by "gradient". Since you've said you've used core graphics to apply a gradient to a shape, then I'll assume you mean that (and not the shadow the previous answer is referring to).

You can't apply a gradient to a border. However, you can create your own border by using a custom shape. The easiest way to do this is to create two paths, an outer path and an inner path. For simplicity sake, let's assume that the path is a simple rect (the rect given in drawRect):

UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];

The second path is going to be an inner path smaller than the first one (enough to make a border):

//To create a 1.0f borderWidth
CGRect innerRect = rect;
innerRect.origin.x += 1.0f;
innerRect.origin.y += 1.0f;
innerRect.size.width -= 2.0f;
innerRect.size.height -= 2.0f;
UIBezierPath *innerPath = [UIBezierPath bezierPathWithRect:innerRect];

Now, append the inner path to the normal path and make sure the path uses the evenOddFillRule. The evenOddFillRule will tell core graphics to only fill the outer portion, leaving the inner portion alone. Oh, and you'll want to clip to the path:

[path appendPath:innerPath];
path.usesEvenOddFillRule = YES;
[path addClip];

If you apply a gradient to this shape, it will fill outside the inner path and inside the outer path, making a border with a gradient.

UPDATE

If you're targeting iOS 5.0 there may be better way to do this. I discovered a remarkable new path function called CGPathCreateCopyByStrokingPath(). See the link for details, but basically it creates a new path that is the stoke(s) of the original, so that if you fill the new path, it would create the same image as stroking the old path. This is fantastic because instead of filling the new path, you can clip to it and then fill with a gradient, giving you a gradient border. This is much easier than the previous method I mentioned, but of course, it's only available in iOS 5.0. This will also make it much easier to create new complex shapes.

like image 90
Aaron Hayman Avatar answered Oct 30 '22 13:10

Aaron Hayman