iOS draw line with both arrow with start-end point while finger touch end and rotate from start or end point - ios

I need help making a drawing demo.
When the user draws a line using their finger,
the line has directional arrows on both ends.
When their finger releases, it draws the line with
"?" (question-mark) in center of the line.
Then, when user taps on the "?", it will show a new view and the user can enter a
value, and the value is in that line.
And we can add multiple lines on capture-image and also we can delete
selected line.
I don't understand how can I start developing these features so
please give me an idea or any link, or suggestion to start develop this
feature.

You should use a UITapGestureRecognizer and a UIBezierPath. Have it so that person taps at one point and then taps at a second point, then make a UIBezierPath between the two points. To get the question mark in the middle you could make it so that the line goes from the first point to (half the distance between point 1 and point 2 - 20pt). And then do the same with the other half of the line (so that you now have a space in the middle of the line.

You can take advantage of the Core Graphics Framework to draw shapes in iOS. This allows you to draw lines, circles, arrows, rectangles etc. Here is some example code to draw a line between 2 points (taken from: How do I draw a line on the iPhone?):
CGContextRef c = UIGraphicsGetCurrentContext();
CGFloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
CGContextSetStrokeColor(c, red);
CGContextBeginPath(c);
CGContextMoveToPoint(c, 5.0f, 5.0f);
CGContextAddLineToPoint(c, 50.0f, 50.0f);
CGContextStrokePath(c);
First define a subclass of UIView to create a space to draw in. Then use a UITapGestureRecognizer to detect taps. As #WyattMufson suggested in his answer, I would get the user to tap once to get the start point of the line and then tap again to get the end point. This is done to ensure that only straight lines can be drawn.
Once you have the start point and end point you can calculate the mid point and connect the two points with a '?' character in between. Then save these line coordinates (start, mid and end points) in some sort of data structure to keep track of all the lines that have been drawn.
When the user taps on a specific line, you can use the saved line coordinates information to detect whether the tap occurred on a line or not (you will have to perform some calculations to do this). If so, display a popover that accepts user input. Once the user inputs a value, close the popover and replace the '?' with the new value.
For line deletion, you could use the UILongPressGestureRecognizer. The user would tap and hold on a drawn line, which would bring up a popover to confirm whether the user wants to proceed with deletion or not. If they do, access the saved line coordinates to detect whether the hold occurred on a line or not. If so, erase that line.
Here are some references to get you started:
How make a simple drawing app with UIKit
How do I draw a line on the iPhone?
Check is a point (x,y) is between two points drawn on a straight line
How to get UITouch location from UIGestureRecognizer

Related

iOS - Find white pixels/area enclosed by a black curve and create path

Using Swift methods touchBegan, touchMoved and touchEnded I save the touch points and than I draw a line using UIGraphicsGetCurrentContext() with methods beginPath(), move(to: Point), addLine(to: Point) and strokePath().
This line is repeated on 4 quadrants plus their negative values, therefore 8 lines are drawn.
Here is an example:
Example image
I save this drawing as an Image when the user taps the tick (Done green button at top-right) for later manipulations.
I wonder if it's possible to create e closed path/shape with white pixels enclosed by the black lines. I want to fill the white area with custom color when the user touches inside it.
The shape is created by user input and I have no idea how it would look like.
Would be thankful to whoever finds the time to give it's contribute.
Thank you
Maybe what you want is the "Flood Fill" algorithm, please see the article.

How to draw multiple circles within circle like target and get touch event of particular circle?

I want to draw target view like this-
And get touch event of a particular circle.
e.g If user touch between circle 7 then fill black color of circles up to circles 7.
Currently I have two ways to implement this functionality:
1) Take 10 UIImageView and put on each other and touch of an image view change the colors of image view's according to conditions.
2) Take UIView and draw 20 color gradient (10 for black border line and 10 for white spaces) and save frame of each gradient. After that get user's touch area then change color according to that.
I am looking for a better solution.
why not have a single image, and calculate the radius based on the touch point - all you need to know is the centre position.
Instead of radius, what you really need is an index from 0 to 11 for your bands - if they are equal thickness, you can do that in a single calculation - take the integer part of (11 * radius / radiusFull)
If the bulls-eye is a different size, you may need to add some more code.
Either way, you should be able to do it all with a single image - generated on the fly, or simply loaded - and a bit of simple maths.

How to detect the coordinates of a custom UIView on CPTPlotspace?

In my App, I am using Coreplot to draw a CPTScatterPlot. Now i want to do a scanner on the chart and this animation of UIView (a line) should be like a Line aligned with Y-axis and travels through x=0 to whatever the last value of x is.
I want to perform an action based on the y value while this custom UIView (scanner) travels.
Any help would be appreciated.
Thanks,
i have something similar in an app of mine, the way i went about it was to add a bar graph on top of the scatter plot, i used that bar graph to represent the line that tracks the user's touch.
then i have a UIView that is overlaid on the plot and tracks the scatter plot touches and displays details of the point being touched.
if you just want to display a line, adding a bar graph is probably the easiest, then you don't have to worry about plot space coordinates vs superview coordinates.
the bar graph data source is only returning a value for the location the user is touching, with a height to match the size of the scatter plot.
the quick version is you can use handlePlotTouchEventInSpace:atPoint:isNewEvent to track the user's touches on the graph.
from there you can use the plotPoint:forPlotAreaViewPoint method on the plot space to get the coordinates of the touch.
something like this is a good starting point. it's a bit of a journey to get it all working, but its not too bad once you get the puzzle started.
-(void)handlePlotTouchEventInSpace:(CPTPlotSpace *)space atPoint:(CGPoint)point isNewEvent:(BOOL)newEvent {
NSDecimal plotPoint[2];
CPTXYPlotSpace *xySpace = (CPTXYPlotSpace *)space;
[xySpace plotPoint:plotPoint forPlotAreaViewPoint:point];
after that plotPoint will contain the x and y location of the touch inside the plot space.

Multiple UIView's overlapping

I am creating multiple custom UIView's in a custom UIView. The creation of the custom sub-views is ok. They look like this:
The draw method is quite straightforward:
[[UIColor brownColor] set];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx,
5.0f);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, 0.0f, 0.0f);
CGContextAddLineToPoint(ctx, 100.0f, 0.0);
CGContextAddLineToPoint(ctx, 130.0f, 25.0f);
CGContextAddLineToPoint(ctx, 100.0f, 50.0f);
CGContextAddLineToPoint(ctx, 0.0f, 50.0f);
CGContextClosePath(ctx);
CGContextStrokePath(ctx);
[super drawRect:rect];
Adding it to the super view is also quite simple:
ITContextFigure *view = [[ITContextFigure alloc] initWithFrame:CGRectMake(location.x, location.y, 135.0f, 50.0f)];
[view setBackgroundColor:[UIColor yellowColor]];
[self addSubview:view];
So my questions are:
1) How can I detect when one overlaps the other?
I saw this solution:
if (CGRectContainsRect([myImageView1 frame], [myImageView2 frame])) {
NSLog(#"Overlaped, it's working!");
}
But if I have multiple UIViews, doing a for on the super view and checking every single sub-view doesn't seem a good solution for me.
2) In this case, what can be done?
My main goal is to detect when this happens:
Update 1.0
Going to try what has been showed here, since there isn't a more elegant way. If I am able to achieve it, I will post the code on Github, if anyone needs it.
You can dramatically cut down on the number of collision detections you need to do by cleverly sorting your data (these are called scan line or seep line algorithms). Here's an outline of how you might apply this technique to your situation.
Sort your subviews into an array ordered by ascending y. If two subviews share the same y order them by ascending x. This is your inactive list and this forms the main input to the algorithm.
The algorithm proceeds as follows.
While there are inactive subviews, choose an active_y. This is the y coordinate of the first subview on the inactive list.
Move all subviews with origins on the active_y line to a working list, sorted by ascending x. This is the active list.
Run through the active list collision testing each each subview with subsequent ones on the list. You do this using two indices into the list (let's call them left and right). As soon as you see a right subview that cannot intersect with the left you can advance the left index.
While doing the collision detection you also check to see if a subview is now completely below the active_y. Once it is, you should remove it from the active list.
The algorithm completes when all the subviews on the inactive list have been consumed and the final run through the active list completed.
This algorithm greatly cuts down on the number of collision detections you will need to perform and is roughly O(n log n), but it can also simplify the collision detection itself.
Since the active list is sorted left to right you always know when you are doing you detection routine which one is on the left and which is on the right. So, for example, when comparing the arrow shapes in your example you only need to check whether the the two leftmost vertices of the right shape fall within the left shape. You may find CGPathContainsPoint useful.
If the number of distinct shapes you are dealing with increases then you might need to consider pushing the collision detection into the scan line algorithm itself. This is a little trickier, but basically instead of the list holding subview pointers they would hold line segments that make up the shapes (excluding horizontal ones).

How to move an UIView along a curved CGPath according to user dragging the view

I'm trying to build a interface that the user can move his finger around the screen an a list of images moves along a path. The idea is that the images center nevers leaves de path.
Most of the things I found was about how to animate using CGPath and not about actually using the path as the track to a user movement.
== Update. Better description ==
I need to objects to be tracked on the path even if the user isn't moving his fingers over the path.
For example (image bellow), if the object is at the beginning of the path and the user touches anywhere on the screen and moves his fingers from left to right I need that the object moves from left to right but following the path, that is, going up as it goes to the right towards the path's end.
== End update
This is the path I've draw, imagine that I'll have a view (any image) that the user can touch and drag it along the path, there's no need to move the finger exactly over the path. If the user move from left to right the image should move from left to right but going up if need following the path.
This is how I'm creating the path:
CGPoint endPointUp = CGPointMake(315, 124);
CGPoint endPointDown = CGPointMake(0, 403);
CGPoint controlPoint1 = CGPointMake(133, 187);
CGPoint controlPoint2 = CGPointMake(174, 318);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, endPointUp.x, endPointUp.y);
CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPointDown.x, endPointDown.y);
Any idead how can I achieve this?
You can take a mathematical function that draws a graph, and then move along this trajectory object.

Resources