Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is a rounded rect view with transparency done on iphone?

A lot of apps pop up a transparent view with rounded corners and an activityIndicator when running a time consuming operation.

How is this rounding done and is it possible to do it just using Interface Builder (as there are lots of places I'd like to use something like this)? Or, should I use an imageview with a rounded rect or stretchable image? Do I need to draw the background myself?

So far, I have managed to get a basic view with similar transparency by setting the alphaValue in Interface Builder however it doesn't have rounded corners, and also the transparency seems to apply to all subviews (I don't want the text and activityindicator to be transparent, however even though I set the alphaValue on those in IB it seems to get ignored).

like image 965
frankodwyer Avatar asked Jun 23 '09 11:06

frankodwyer


3 Answers

As of iPhone SDK 3.0, you can simply use the layer's cornerRadius property. E.g.:

view.layer.cornerRadius = 10.0;

Along the same lines, you can change the view's border color and width:

view.layer.borderColor = [[UIColor grayColor] CGColor];
view.layer.borderWidth = 1;
like image 124
Mirko Froehlich Avatar answered Oct 22 '22 04:10

Mirko Froehlich


view.layer.cornerRadius = radius;

The hard way (that used to be required in the first iPhone SDK) is to create your own UIView subclass with drawRect: method:

 CGContextRef context = UIGraphicsGetCurrentContext();
 CGContextSetRGBFillColor(context, 0,0,0,0.75);

 CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius);
 CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius);
 CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, 
                radius, M_PI, M_PI / 2, 1); //STS fixed
 CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, 
                        rect.origin.y + rect.size.height);
 CGContextAddArc(context, rect.origin.x + rect.size.width - radius, 
                rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
 CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius);
 CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, 
                radius, 0.0f, -M_PI / 2, 1);
 CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y);
 CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius, 
                -M_PI / 2, M_PI, 1);

 CGContextFillPath(context);

Note: rect in this code should be taken from [self bounds] (or whatever location you want it in), it won't make sense with rect passed to drawRect: method.

like image 47
Kornel Avatar answered Oct 22 '22 05:10

Kornel


I abstracted out @lostInTransit's response into this function:

static void ContextAddRoundedRect(CGContextRef c, CGRect rect, CGFloat radius) {
  CGFloat minX = CGRectGetMinX(rect);
  CGFloat maxX = CGRectGetMaxX(rect);
  CGFloat minY = CGRectGetMinY(rect);
  CGFloat maxY = CGRectGetMaxY(rect);

  CGContextMoveToPoint(c, minX + radius, minY);
  CGContextAddArcToPoint(c, maxX, minY, maxX, minY + radius, radius);
  CGContextAddArcToPoint(c, maxX, maxY, maxX - radius, maxY, radius);
  CGContextAddArcToPoint(c, minX, maxY, minX, maxY - radius, radius);
  CGContextAddArcToPoint(c, minX, minY, minX + radius, minY, radius);
}

which places the path onto the context for you to do with as you may

slightly different CoreGraphics calls and i didn't close the path, in case you want to add that

CGContextFillPath(c);
like image 8
bshirley Avatar answered Oct 22 '22 05:10

bshirley