How to create round shape UIview instead of rectangle shape - iphone

Hi in my application i need a view which is of round shape instead of a rectangle shape. How to create a uiview object of round shape please let me know. Thanks in advance.

Technically, all UIView's will always be "rectangles", meaning they will be placed on the screen using {x, y} coordinates and they will be dimensioned with a height and a width (Making them rectangles). However, within the bounds of a UIView you can do a lot to make it appear as a circle. Here are some methods:
Use UIImageView and set it's Image to be an image of a circle. This is easy, but not very flexible.
Learn Core Graphics (also known as Quartz2D) and draw a circle in the UIView's -drawRect: method. Quartz 2D Programming Guide
Use a CAShapeLayer for the UIView's layers. CAShapeLayer Class Reference
There are certainly other methods but this should be a good start. If you need to detect touches within the circle, you can use either option 2. or 3. and keep a reference to the CGPathRef (or UIBezierPath) and use CGPathContainsPoint to determine if the touch is within the bounds of the circle and act accordingly.

You can set the cornerRadius of the layer of your view.
#import <QuartzCore/QuartzCore.h>
yourView.layer.cornerRadius = 20;

Related

CAShapeLayer Line drawing

I am drawing line over 5 custom uiviews (Like UITableView rows) from one position to another (X,Y axis) using CAShapeLayer.
My issue is that I want to know that what view the CAShapeLayer (line in my case) is currently in. Is there any CGIntersect for CALayer and CGRect etc? I am trying to create graph using core animation instead of any chart API.
You could check in the shape layer intersects a specific layer by checking intersection of the bounding box of the path agains the frame of the other layer.
BOOL doesIntersect = CGRectIntersectsRect(CGPathGetBoundingBox(path), layer.frame);

Arc's position on circle

I've got few pixels wide circle (circle is UIBezierPath based). I have to put an arc (which is basically UIView subclass with custom drawing) on the circle so the arc covers circle. I know how to calculate rotation of arc and position but something is not right. I mean I know the reason - it's beacause center property which is assigned to center of UIView, if it was center of the arc, everything would be great. But it's not.
I also know how to solve that. I have to calculate smaller radius where I will put arcs on. But how to do that. Basically it seems easy but because of the arc is in rectangular UIView it gets a bit harder. I'll show you some images so you can see the problem.
The easiest way to do this is to change the anchor point of each arc view's layer. You can read about the anchor point here if you don't already know about it.
You will need to add the QuartzCore framework to your build target and add #import <QuartzCore/QuartzCore.h>.
CGRect circleBounds = circleView.bounds;
topArcView.layer.anchorPoint = CGPointMake(.5, 0);
topArcView.layer.position = CGPointMake(CGRectGetMidX(circleBounds), 0);
bottomArcView.layer.anchorPoint = CGPointMake(.5, 1);
bottomArcView.layer.position = CGPointMake(CGRectGetMidX(circleBounds), CGRectGetMaxY(circleBounds));
leftArcView.layer.anchorPoint = CGPointMake(0, .5);
leftArcView.layer.position = CGPointMake(circleBounds.origin.x, CGRectGetMidY(circleBounds));
rightArcView.layer.anchorPoint = CGPointMake(1, .5);
rightArcView.layer.position = CGPointMake(CGRectGetMaxX(circleBounds), CGRectGetMidY(circleBounds));
Perhaps you could make the UIView subclass the same size and center point as the circle's rect. Then draw the arc in the correct location.

How to Size UIView from its CALayers?

I have a UIView with a hierarchy of CALayers.
I am creating the layers using images, so I don't know the final size of the UIView until I have completed creating the layers.
How would I find out a final UIView size that allows touches to all the layers?
It's also complicated by the fact that a layer might be rectangular, and then rotated, so that it sticks out further. I wouldn't be able to use the frame size of the layer, because of its affine transform.
I do have a solution that makes one UIView the size of the screen, and I can add all my CALayers to this UIView, but I will have several sets of these layer hierarchies, which I would prefer to be in separate UIViews so that I can use UIView gestures to translate/scale/rotate.
You can use CGMutablePathRef for this. And then loop over all CALayer-s in view.layer.sublayers:
CGPathAddRect(path,
&transform,
CGRectOffset(i.bounds,
-CGRectGetMidX(i.bounds),
-CGRectGetMidY(i.bounds)));
Rectangle is offset to have its center in CGPointZero. The transform here is rotation of your layer (or scale) plus translation to layer's position. I.e.:
CGAffineTransform transform =
CGAffineTransformConcat(CATransform3DGetAffineTransform(i.transform),
CGAffineTransformMakeTranslation(i.position.x,
i.position.y));
Finally:
view.bounds = CGPathGetBoundingBox(path);
Bounds now are minimal and enclose all layers.

Best way to flip a UIImage in a CALayer who's origin is not at (0,0)

Greetings... I come in peace, shoot to kill...
I have a container of type UIView (A Grid) and add many sublayers to the layer of the UIView (CALayers representing cells within the grid).
Within the Cell, I render many UIImages at different locations using CGContextDrawImage. I am well aware of the need to Translate and Scale, but the scaling (flipping) is with reference to the superviews (Grid) co-ordiantes and the origin of the Cell CALayer is not (0,0).
Therefore my rendering is all over the shop (mostly off screen). What is the best way to handle the translating and scaling when the UIImage is not at (0,0). Is there an established design pattern I should be using.
I solved this issue by just manually offsetting the translation by double the y origin.

How do I draw a point inside of an instance of UIImageView?

How do I use Core Graphics to draw inside of a instantiated UIImageView (No class files to override drawrect with -- just a reference to the instance)? I want to draw a simple point of fixed width (say, 10 pixels diameter) and of a certain color.
How do I use Core Graphics to … draw a simple point of fixed width (say, 10 pixels diameter) and of a certain color[?]
Set the fill color.
Move to the point.
Plot an arc, centered at the point, with the desired radius, giving a start angle of 0 and an end angle of 2 * M_PI.
Close the path.
Fill.
… draw inside of a instantiated UIImageView (No class files to override drawrect with -- just a reference to the instance)
I know that on the Mac, that's really not a good idea, as an NSView may redraw at any time if anything has set it as needing display (or told it directly to display), and would then clobber anything you'd drawn over it. No idea about the iPhone, but I do notice that UIView doesn't have methods like NSView's lockFocus and unlockFocus.
There's a more architectural reason not to do this: Drawing is the exclusive domain of views, and you're proposing to break that exclusivity and sprinkle some drawing code in (I'm assuming) a controller. Scattering code for a purpose in an object that doesn't have that purpose is a path to messy, unnavigable code.
Better to make a subview for each point and add those as subviews of the image view, or subclass UIImageView, give your instance of that subclass an array of the points to draw, and have the subclass's drawRect: call up to super before drawing its points.
The above solution, then, goes in drawRect:.
You can also just add a Core Animation layer to the view. Set the corner radius to half the size of the point you want (assuming a square) and it will render as a circle. Something like:
CALayer *layer = [CALayer layer];
[layer setBounds:CGRectMake(0.0f, 0.0f, 10.0f, 1.0f)];
[layer setCornerRadius:5.0f];
[layer setMasksToBounds:YES];
[layer setBackgroundColor:[[UIColor redColor] CGColor]];
// Center the layer in the view.
[layer setPosition:CGPointMake([view bounds].size.width/2,
[view bounds].size.height/2)];
// Add the layer to your view
[[view layer] addSublayer:layer];
Not Core Graphics exactly, but it's easy to implement.
Best Regards,