UIPopover in ipad - iphone

I would like to create something like this:
The copy, star, reply, details. Is this just a UIPopover with a segmented button on it?
Here's another example of what I want:
Anyone got something like this?

The class you are looking for is UIMenuController
This SO page has a lot of useful information.

No. Ive been trying to recreate that view with a UIPopoverViewcontroller, holding a UIViewController with a UISegment.. and Im not getting that same functionality. The main issue is the UIPopoverVC is giving me a 3d border around my viewcontroller/view.
It does appear that its a custom view. Which, on that note, would not be too difficult to create by the way, and that view can host your SegmentedViewController, just not in a UIPopoverVC.
And.. for your viewing enjoyment... here is the code that creates the CGPath for a "Balloon" view like the Popover creates. this code goes in your drawRect.
float radius=5; //corner radius
CGContextSaveGState(context);
CGContextBeginPath(context);
CGContextSetRGBFillColor(context, backColor.red,backColor.green,backColor.blue,backColor.alpha);
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);
CGContextMoveToPoint(context, rect.size.width/2, rect.size.height);
CGContextAddLineToPoint(context, rect.size.width/2, rect.size.height+10);
CGContextAddLineToPoint(context, rect.size.width/2+10, rect.size.height);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextRestoreGState(context);

Related

I need help to draw a pointer on a map callout

I have no experience in Quartz drawing.
I need to draw a rectangle on callout view. i found some sample code to draw it.
My current code for that is
- (void)drawRect:(CGRect)rect {
CGFloat stroke = 1.0;
CGFloat radius = 7.0;
CGMutablePathRef path = CGPathCreateMutable();
UIColor *color;
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat parentX = [self relativeParentXPosition];
//Determine Size
rect = self.bounds;
rect.size.width -= stroke + 14;
rect.size.height -= stroke + 14 + CalloutMapAnnotationViewHeightAboveParent;
rect.origin.x += stroke / 2.0 + 7;
rect.origin.y += stroke / 2.0 + 7;
//Create Path For Callout Bubble
CGPathMoveToPoint(path, NULL, rect.origin.x, rect.origin.y + radius);
CGPathAddLineToPoint(path, NULL, rect.origin.x, rect.origin.y + rect.size.height - radius);
CGPathAddArc(path, NULL, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, radius, 0.0f, M_PI / 2, 1);
CGPathAddLineToPoint(path, NULL, parentX - 15, rect.origin.y + rect.size.height);
CGPathAddLineToPoint(path, NULL, parentX, rect.origin.y + rect.size.height + 15);
CGPathAddLineToPoint(path, NULL, parentX + 15, rect.origin.y + rect.size.height);
CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height);
CGPathAddArc(path, NULL, rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1);
CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y + radius);
CGPathAddArc(path, NULL, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, radius, 0.0f, -M_PI / 2, 1);
CGPathAddLineToPoint(path, NULL, rect.origin.x + radius, rect.origin.y);
CGPathAddArc(path, NULL, rect.origin.x + radius, rect.origin.y + radius, radius, -M_PI / 2, M_PI, 1);
CGPathCloseSubpath(path);
//Fill Callout Bubble & Add Shadow
color = [[UIColor blackColor] colorWithAlphaComponent:.6];
[color setFill];
CGContextAddPath(context, path);
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake (0, self.yShadowOffset), 6, [UIColor colorWithWhite:0 alpha:.5].CGColor);
CGContextFillPath(context);
CGContextRestoreGState(context);
//Stroke Callout Bubble
color = [[UIColor darkGrayColor] colorWithAlphaComponent:.9];
[color setStroke];
CGContextSetLineWidth(context, stroke);
CGContextSetLineCap(context, kCGLineCapSquare);
CGContextAddPath(context, path);
CGContextStrokePath(context);
//Determine Size for Gloss
CGRect glossRect = self.bounds;
glossRect.size.width = rect.size.width - stroke;
glossRect.size.height = (rect.size.height - stroke) / 2;
glossRect.origin.x = rect.origin.x + stroke / 2;
glossRect.origin.y += rect.origin.y + stroke / 2;
CGFloat glossTopRadius = radius - stroke / 2;
CGFloat glossBottomRadius = radius / 1.5;
//Create Path For Gloss
CGMutablePathRef glossPath = CGPathCreateMutable();
CGPathMoveToPoint(glossPath, NULL, glossRect.origin.x, glossRect.origin.y + glossTopRadius);
CGPathAddLineToPoint(glossPath, NULL, glossRect.origin.x, glossRect.origin.y + glossRect.size.height - glossBottomRadius);
CGPathAddArc(glossPath, NULL, glossRect.origin.x + glossBottomRadius, glossRect.origin.y + glossRect.size.height - glossBottomRadius, glossBottomRadius, M_PI, M_PI / 2, 1);
CGPathAddLineToPoint(glossPath, NULL, glossRect.origin.x + glossRect.size.width - glossBottomRadius, glossRect.origin.y + glossRect.size.height);
CGPathAddArc(glossPath, NULL, glossRect.origin.x + glossRect.size.width - glossBottomRadius, glossRect.origin.y + glossRect.size.height - glossBottomRadius, glossBottomRadius, M_PI / 2, 0.0f, 1);
CGPathAddLineToPoint(glossPath, NULL, glossRect.origin.x + glossRect.size.width, glossRect.origin.y + glossTopRadius);
CGPathAddArc(glossPath, NULL, glossRect.origin.x + glossRect.size.width - glossTopRadius, glossRect.origin.y + glossTopRadius, glossTopRadius, 0.0f, -M_PI / 2, 1);
CGPathAddLineToPoint(glossPath, NULL, glossRect.origin.x + glossTopRadius, glossRect.origin.y);
CGPathAddArc(glossPath, NULL, glossRect.origin.x + glossTopRadius, glossRect.origin.y + glossTopRadius, glossTopRadius, -M_PI / 2, M_PI, 1);
CGPathCloseSubpath(glossPath);
//Fill Gloss Path
CGContextAddPath(context, glossPath);
CGContextClip(context);
CGFloat colors[] =
{
1, 1, 1, .3,
1, 1, 1, .1,
};
CGFloat locations[] = { 0, 1.0 };
CGGradientRef gradient = CGGradientCreateWithColorComponents(space, colors, locations, 2);
CGPoint startPoint = glossRect.origin;
CGPoint endPoint = CGPointMake(glossRect.origin.x, glossRect.origin.y + glossRect.size.height);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
//Gradient Stroke Gloss Path
CGContextAddPath(context, glossPath);
CGContextSetLineWidth(context, 2);
CGContextReplacePathWithStrokedPath(context);
CGContextClip(context);
CGFloat colors2[] =
{
1, 1, 1, .3,
1, 1, 1, .1,
1, 1, 1, .0,
};
CGFloat locations2[] = { 0, .1, 1.0 };
CGGradientRef gradient2 = CGGradientCreateWithColorComponents(space, colors2, locations2, 3);
CGPoint startPoint2 = glossRect.origin;
CGPoint endPoint2 = CGPointMake(glossRect.origin.x, glossRect.origin.y + glossRect.size.height);
CGContextDrawLinearGradient(context, gradient2, startPoint2, endPoint2, 0);
//Cleanup
CGPathRelease(path);
CGPathRelease(glossPath);
CGColorSpaceRelease(space);
CGGradientRelease(gradient);
CGGradientRelease(gradient2);
}
this is the current callout i am getting.But i need to draw that triangle shape at the edge at the top of the rectangle.
by studding it these 2 two lines i need to change
CGPathAddLineToPoint(path, NULL, parentX - 15, rect.origin.y + rect.size.height);
CGPathAddLineToPoint(path, NULL, parentX, rect.origin.y + rect.size.height + 15);
but i am poor in quartz graphics.
my required callout is like below image
triangle need to up of the callout view.
people who have knowledge on quartz graphics please help me.
Well, if you're looking for the callout to be on the top, try this. Replace the path for the callout bubble with the following:
//Determine Size
rect = self.bounds;
rect.size.width -= stroke + 14;
rect.size.height -= stroke + 14 + CalloutMapAnnotationViewHeightAboveParent;
rect.origin.x += stroke / 2.0 + 7;
rect.origin.y += stroke / 2.0 + 7 + 14;
//Create Path For Callout Bubble
CGPathMoveToPoint(path, NULL, rect.origin.x, rect.origin.y + radius);
CGPathAddLineToPoint(path, NULL, rect.origin.x, rect.origin.y + rect.size.height - radius); //Left line
CGPathAddArc(path, NULL, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, radius, 0.0f, M_PI / 2, 1); //Bottom left arc
// CGPathAddLineToPoint(path, NULL, parentX - 15, rect.origin.y + rect.size.height); //bottom to callout line
// CGPathAddLineToPoint(path, NULL, parentX, rect.origin.y + rect.size.height + 15); //callout left
// CGPathAddLineToPoint(path, NULL, parentX + 15, rect.origin.y + rect.size.height); //callout right
CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height); //bottom to right line
CGPathAddArc(path, NULL, rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height - radius, radius, M_PI / 2, 0.0f, 1); //bottom right
CGPathAddLineToPoint(path, NULL, rect.origin.x + rect.size.width, rect.origin.y + radius); //right line
CGPathAddArc(path, NULL, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, radius, 0.0f, -M_PI / 2, 1); //top right
CGPathAddLineToPoint(path, NULL, parentX + 15, rect.origin.y); //top right to right callout
CGPathAddLineToPoint(path, NULL, parentX, rect.origin.y - 15); //callout right
CGPathAddLineToPoint(path, NULL, parentX - 15, rect.origin.y); //callout left
CGPathAddLineToPoint(path, NULL, rect.origin.x + radius, rect.origin.y); //top left callout to top left
CGPathAddArc(path, NULL, rect.origin.x + radius, rect.origin.y + radius, radius, -M_PI / 2, M_PI, 1); //top left
CGPathCloseSubpath(path); //Path closed, no line draw
I believe this should work (haven't tested it). But the gloss path is dependent on that callout rect being used so I think everything else should work fine.
As a side note, Core Graphics involves drawing paths kind of like drawing on a piece of paper. A CGPathMoveToPoint involves putting the pencil down. Everything after that is drawing either lines or arcs sequentially. All you need to do is read the point that the line/curve is being drawn to. Note that arcs are translated into curves, but to read them you need to know where pi, pi/2 and pi/4 is on a unit circle. That tells you where the arc is being drawn. But in general, you can assume (at least in this case) that the arc is corresponding to the actual corner the previous line was drawn to. I added comments indicating what path elements correspond to what part of the box. I also commented out the bottom callout rather than delete it. You can uncomment it to draw the bottom callout again but you'll need to remember to comment out the top and shift the rect back up (I shifted it down by 14). Also consider avoiding using 'magic numbers', like the size of the callout (15) and instead put something like this in your file:
#define CalloutSize 15.0f
Doing this and inserting CalloutSize into the code rather than 15 will allow you to easily change it's size without having to search for each instance it's being used.

Why is my CoreGraphics shape not showing a border?

This is the code I have:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, rect);
CGContextSetFillColorWithColor(context, [BUTTON_COLOR CGColor]);
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
CGContextSetLineWidth(context, 1);
int radius = CORNER_RADIUS;
CGContextMoveToPoint(context, 0, self.frame.size.height / 2);
CGContextAddLineToPoint(context, POINT_WIDTH, self.frame.size.height);
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, POINT_WIDTH, 0);
CGContextAddLineToPoint(context, 0, self.frame.size.height / 2);
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);
Why is it not drawing a border around the shape?
EDIT: Now it draws the shape, thanks to changing the last line, but it draws an extra line around it, like this:
http://cl.ly/0u0e051a060m161u0n08
Use CGContextDrawPath(context, kCGPathFillStroke) instead of CGContextFillPath() and CGContextStrokePath().
The thing is, after the first call to CGContextFillPath() or CGContextStrokePath() the context's path is cleared, so the second call does not have a path to work with.

How to change the color of hud place of gray color

My question is the "How to change the color of the HUD in place of gray color"
In hud their is a gray color for the hud.
How to change the color of that color replace with off green color
in below image their is hud and how to change the gray color replace with another off green color
Thanks in advance.
Nimit Parekh.
MBProgressHUD *HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
HUD.color = [UIColor purpleColor];
...
Swift 3:
let hud:MBProgressHUD = MBProgressHUD.showAdded(to: self.view, animated: true)
hud.bezelView.color = UIColor.green // Your backgroundcolor
hud.bezelView.style = .solidColor // you should change the bezelview style to solid color.
_mHud.bezelView.color = [UIColor blackColor];
_mHud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
_mHud.contentColor = [UIColor whiteColor];
I founding out the solution of this problem and implemented into my project.
In Following method is use into the MBProgressHud.m their is a manage the color of the Hud background color so the change color for that we change the value of the CGContextSetRGBFillColor argument change.
If apply this value then we gets the green color of the hud.
- (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context {
float radius = 10.0f;
CGContextBeginPath(context);
CGContextSetRGBFillColor(context, 17.0/255, 64.0/255, 42.0/255, 0.8);
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);
}
MBProgressHUD.m has a "drawRect:(CGRect)rect" method where you will find the gray color set in CGContext function:
CGContextSetGrayFillColor (context, 0.0f, self.opacity);
You can just substitute CGContextSetGrayFillColor by another function that uses RGB (or other) color type:
CGContextSetRGBFillColor (context, 0/255.0f, 132/255.0f, 200/255.0f, 0.9f);
Check complete CGContext reference here:
Version 0.8 of MBProgressHud let's you set the color in its init method:
It is set to nil by default.
in MBProgressHUD.m:
- (id)initWithFrame:(CGRect)frame {
.
.
.
self.color = [UIColor greenColor];

Corners from CGContextAddArc are too dark

i have little problem with my code. I want to add a footer to a uitableview-section, but that's not my problem.
My problem is that i want to have rounded corners on my footer-view, but not on all corners, just the two on the bottom. But the corners are just too dark and i don't know why...
Heres my code:
- (void)drawRect:(CGRect)rect {
float radius = 10.0f;
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat strokeColorArray[4] = {0.35f,0.35f,0.35f,1.0f};
CGContextSetStrokeColor(context, strokeColorArray);
CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1);
CGContextSetLineWidth(context, 1.0);
CGContextBeginPath(context);
CGContextMoveToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));
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);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextMoveToPoint(context, CGRectGetMaxX(rect), CGRectGetMinY(rect));
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);
CGContextAddLineToPoint(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextDrawPath(context, kCGPathStroke);
}
Here's a picture of my problem:
http://img195.imageshack.us/img195/9834/bildkw.png
Can you see the darker corners? How can i fix that?
Thank you
Sebastian
There's a couple things you can try. One is to change the radius of the corners. Another is to add some code to make sure that you draw lines on the inside of the rectangle and instead of centering the lines on the edges. To do that, you would have to inset the rect by half of the line width, or 0.5 pixels in this case.

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).
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;
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.
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);
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
MBProgressHUD....
http://www.cocoadev.com/index.pl?MBProgressHUD