views:

6317

answers:

5

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).

+10  A: 

I'm surprised that Apple doesn't provide this out of the box. You have 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 / 4, M_PI / 2, 1);
 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.

porneL
thanks! will try that.
frankodwyer
Do I still set transparency and bg color etc through IB and how do I stop the alpha applying to the subviews (text/activityIndicator)? At least I think that is what happens - both the text and the spinner look very anemeic/grey, like the background is coming through the white text.
frankodwyer
Set transparent background in IB, and use semitransparent fill color in the code. I've updated the answer.
porneL
works great. one minor point it is missing the 'float radius=0.5f;' that it needs to compile (oddly enough I also left out 'rect=self.bounds and it still worked)
frankodwyer
+4  A: 

In your view do this in the drawRect method

float radius = 5.0f;

CGRect rect = self.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();   
rect = CGRectInset(rect, 1.0f, 1.0f);

CGContextBeginPath(context);
CGContextSetGrayFillColor(context, 0.5, 0.7);
CGContextMoveToPoint(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect));
CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMinY(rect) + radius, radius, 3 * M_PI / 2, 0, 0);
CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMaxY(rect) - radius, radius, 0, M_PI / 2, 0);
CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMaxY(rect) - radius, radius, M_PI / 2, M_PI, 0);
CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect) + radius, radius, M_PI, 3 * M_PI / 2, 0);

CGContextClosePath(context);
CGContextFillPath(context);

This will make your rounded rectangle for your view. You can find a complete example in the HeadsUpUI sample provided with the SDK. HTH

lostInTransit
A: 

Hi frankodwyer,

actually i have used this transparency some time in the past, there is one function available where it will take the string name and that is displayed on the transparent view with the activity indicator, if possible can anyone find it and let me know, as i am very much in need of it now , please anyone ......

Thank you,

Lakshmikanth.

+16  A: 

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;
Mirko Froehlich
any idea how I can get a margin between the border and the content in the UILabel?
david
I'm not aware of any way to do that. With a UIButton, you should be able to use the contentEdgeInsets property, but UILabel doesn't seem to have anything like that. Perhaps just create a UIView with border and rounded corners, then add your UILabel as a subview, slightly inset.
Mirko Froehlich
That works like a charm, thx!
david
You may need to `#import <QuartzCore/QuartzCore.h>` if you get an error trying to access the `layer` property. Otherwise, this is a great alternative to manually drawing the rounded corners, and by not having to implement a custom `drawRect:`, it works for simple container views.
Steve Madsen
You might also have to add: view.layer.masksToBounds = YES; if your image extends beyond the corner radius.
Ward
+1  A: 

MBProgressHUD....
http://www.cocoadev.com/index.pl?MBProgressHUD

casey