Slice a UIImageView into a custom shape - iphone

I have a UIImageView that contains an image of a circle. I would like to be able to remove a portion of the image (while maintaining the transparency) to create the effect of a slice missing as shown below. My ultimate goal is to create something like the ITunes app, where as you play a song preview, the circle slowly fills in, in a clockwise direction.

If you don't need the image of the circle for anything other than the progress display, you could skip the UIImageView and just use CoreGraphics to draw the progress indicator. The basic steps would be:
Create a path - CGContextBeginPath
Add an arc using CGContextAddArc
Fill the path using CGContextFillPath
Close the path - CGContextClosePath
Repeat this for each progress step, changing the endpoint of your arc each time.

I've implemented a similar filling-up circle with the following code:
(the delegate provides a value between 0 and 1)
- (void)drawRect:(CGRect)rect
{
CGFloat endAngle=([self.delegate giveCompletion]+0.75)*2*M_PI;
UIBezierPath *path=[UIBezierPath bezierPathWithArcCenter:self.center radius:self.bounds.size.width/(3) startAngle:0.75*2*M_PI endAngle:endAngle clockwise:YES];
[path addLineToPoint:self.center];
[path addLineToPoint:CGPointMake(self.center.x, self.center.y+self.bounds.size.width/(3)) ];
[path addClip];
[[UIColor blueColor]setFill];
UIRectFill(self.bounds);
}
I haven't figured out how to dynamically make it fill up yet, though I guess that this would depend heavily on the specific context where it is being used. Hope it is of any help! Cheers.

Related

Custom Pattern Pencil Sketch Drawing

Using Core Graphics, I want the painting app functionality and here the user can have the custom image pattern drawing functionality.I followed the proceeding snippet :
enter code here
UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0f];
[T_BImage drawAtPoint:CGPointMake(rotX-(T_BImage.size.width)/2, rotY-(T_BImage.size.height)/2) blendMode:kCGBlendModeNormal alpha:1.0f];
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Here , is the output.
But ,when the user continuously drags fast on the screen , then the image is not sequentially drawn whereas the same code works fine with slow drag
Any help will be appreciated.
The problem with your code is as the drag speeds up, there will be continuous calls to the same method which might be rendering this slow. If you are planning to paint the pattern image, I suggest you try and look into the apple sample code here
You will have to replace the pattern image in the above sample project with your custom pattern image. See how it goes. One point to be noted is that the pattern image has to be square shaped(same width and height)
Finally, the image is drawn with the direct proportion of user's drawing speed. This was achieved by calculating the smallest set of points between touches_began and touches_moved delegate methods.i.e. All the set of possible points from minimum (starting) CGPoint to Maximum(Inbetween moving or end)point was manually calibrated and those points are passed through the image drawing function concurrently with separate thread.
Thanks to Brad-Larson for his remarkable .
response

How to create round shape UIview instead of rectangle shape

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;

iPhone: Line connectors attached to shapes

How would you draw a line connector between two shapes, such that the line draws with the proper angles and move along with any movement of the shapes?
Something like this:
I imagine a UIBezier Curve is what I need, but any tutorials or help in getting started would be appreciated.
I think UIBezierPath is the right way to go, so you should definitely read up on it. I wrote a quick example for making a path there are many more options I'm not using.
Drawing the paths is not the difficult part. You'll have to track all the boxes you create and store the connections between them somehow, it depends greatly on how you store the boxes but a relational database feels like the right solution. Given these objects and connections, you'll generate paths in drawrect for one of your views.
- (void)drawRect:(CGRect)rect {
// say we already created a "Make" box
UIBoxThing *make = ...
// and here we already created a "Diagrams" box
UIBoxThing *diagrams = ...
[[UIColor blackColor] setStroke];
// since we know Diagrams and Make are connected (via some other data), we must draw an arrow between them
UIBezierPath *path = [[UIBezierPath alloc] init];
path.lineWidth = 2;
// the midpoint of the right side of our first box
CGPoint start = CGPointMake(make.frame.origin.x+make.frame.size.width, make.frame.origin.y+(make.frame.size.height/2));
[path moveToPoint:start];
// the midpoint of the left size of our second box
CGPoint end = CGPointMake(diagram.frame.origin.x, diagram.frame.origin.y+(diagram.frame.size.height/2));
[path addLineToPoint:end];
[path stroke];
}
This would be complimented with code that can tell if boxes are to the right of one another or the left, and you can bend the line with addCurveToPoint: or a number of other methods on UIBezierPath. Most of the path stuff is depending on your style, there's no one correct style to connect two points.

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.

Is it ever possible to call pointInside: on an irregular shape?

I'm drawing an oblong 'egg' shape (on iOS), and want to use it as a boundary for particles. My thought is to use the curve paths to make a UIView and then use hitTest:withEvent: or pointInside:withEvent: to enforce boundary collision.
The problem is, of course, that UIView is always rectangular. How would you go about checking to see if a point is inside an irregular shape like this?
- (void)drawRect:(CGRect)rect {
int w = rect.size.width;
int h = rect.size.height;
CGContextBeginPath(context);
CGContextMoveToPoint(context, w/2, h/5);
CGContextAddCurveToPoint(context, w*0.1, h/4.3, w*0.1, h*0.82, w/2, h*0.8);
CGContextAddCurveToPoint(context, w*0.9, h*0.82, w*0.9, h/4.3, w/2, h*0.2);
I'm using openFrameworks, for what that's worth. This code is just Obj-C but I'm open to any C++/obj-C++ solutions out there.
If you make a CGPathRef you can use CGPathContainsPoint. You can use that same CGPathRef to render into the context. You could also call CGContextPathContainsPoint on the context containing the path, but depending on when you need to test you might not have a context. And another alternative is the containsPoint selector on UIBezierPath.
If you want to code this from scratch, http://www.softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm goes through a couple of different algorithms that will work for an arbitrary polygon.