How to display dashed lines in objective-c? - ios

I have this code to display a grid with dashed line. In runtime on an iphone 5 below it shows fine, but if I run the app on iphone 5s there's no grid. I tested in iPhone Simulator and on real devices and happens the same.
Here's the code:
if (self.dashLongitude) {
CGFloat lengths[] = {3.0, 3.0};
CGContextSetLineDash(context, 0.0, lengths, 2);
}
//other stuff here
CGContextSetLineDash(context, 0, nil, 0);
So anyone could help??
EDIT: Hey guys I solved the issue using the same code I posted here, but in a different method. So I have now two methods: one just for the drawing the grid and another on to draw the line with data and finally got everything working.

The code looks fine.
As I look into the code I saw you are setting the nil in the context. nil is used to remove the dashed line.
Try to use
CGFloat dash[] = {2.0, 2.0};
CGContextSetLineDash(context, 0.0, dash, 2);
where you are creating or provide stroke your line(underneath).
CGContextSetLineDash(context, 0, NULL, 0);
is used to remove that dash pattern.

Instead of setting nil in CGContextSetLineDash, just wrap your code into CGContextSaveGState/CGContextRestoreGState to preserve context state before applying line dash:
CGContextSaveGState(context);
CGFloat dash[] = {2.0, 2.0};
CGContextSetLineDash(context, 0.0, dash, 2);
// Draw some lines here
CGContextRestoreGState(context);

Related

iOS the quality of drawing lines using CGContext is much worse than SKShapeNode in SpriteKit

I'm making a game where the user can draw lines with finger. There are tons of methods on websites. I tried two methods, one using CGContext in UIView (UIKit), and the other using CGPath and SKShapeNode in SpriteKit. But the latter shows much better quality. The first one using CGContext has ugly rough edges.
Please see following screen shots. I also attached part of code for both methods here, (in the touchesMove function).
Note: var ref = CGPathCreateMutable()
CGContext in UIView
CGPathAddLineToPoint(ref, nil, currentPoint.x, currentPoint.y)
UIGraphicsBeginImageContext(self.frame.size)
let context = UIGraphicsGetCurrentContext()
tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height))
CGContextAddPath(context, ref)
// 3
CGContextSetLineCap(context, CGLineCap.Round)
CGContextSetLineWidth(context, brushWidth)
CGContextSetRGBStrokeColor(context, red, green, blue, 1.0)
CGContextSetBlendMode(context, CGBlendMode.Normal)
// 4
CGContextStrokePath(context)
// 5
UIGraphicsEndImageContext()
SKShapeNode in SpriteKit
Note: var lineDrawing = SKShapeNode()
CGPathAddLineToPoint(ref, nil, location.x, location.y)
lineDrawing.path = ref
lineDrawing.lineWidth = 3
lineDrawing.strokeColor = UIColor.blackColor()
lineDrawing.alpha = 1.0
self.addChild(lineDrawing)
How can I draw lines in UIView with the same quality of SKShapeNode?
One obvious problem is that you're using an outdated function that doesn't handle Retina screens:
UIGraphicsBeginImageContext(self.frame.size)
You should be using this instead:
UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0)
The WithOptions version, with 0 as the final argument, creates an image context at Retina resolution if the device has a Retina screen. (The 0 argument means “use the device screen's scale factor”.)
There may be other issues, because you didn't show the code that creates the points in the path for each test case.

CGAffineTransform on OpenGL view and its affect on view size

I am debugging an issue in which a library I am using creates an OpenGL view, and triggers a memory warning.
One thing I noticed is that setting the view to a fraction of the window size causes it to work fine. When debugging via the view via XCodes interface debugger I see that the bounds of the view go well out past the bounds of the parent view. When printing the view in question I see this:
<RenderView: 0x140a61d10; frame = (5 0; 1019 728); transform = [1019, 0, 0, 728, 0, 0]; layer = <CALayer: 0x140ad0a40>>
I am unfamiliar with this, but from reading the CGAffineTransform docs it seems that the variables being set are "a" and "d" which correspond to the scale sx and sy.
So my question is would this transform actually be displaying a view which is 1019*1019 x 728*728, does this seem suspicious? likely a bug in the library, or is my understand incorrect?
I am seeing this issue using Xcode 7, on multiple devices, currently testing on a iPad Pro 9.7 running 9.3.1.
Here's clarification on what goes where between a 2x3 CGAffineTransform and a GLKMatrix4...
Your CGAffineTransform that represents the preferred or actual transform of your view or asset dimensions and orientation (or aspect) translate to a GLKMatrix4 (or mat4, which is multiples against the position in your vertex shader), thusly:
CGAffineTransform preferredTransform= [videoTrack preferredTransform];
GLfloat preferredTransformMatrix[] = {
preferredTransform.a, preferredTransform.b, preferredTransform.tx, 0.0,
preferredTransform.c, preferredTransform.d, preferredTransform.ty, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
This is just an example showing the correct positions for each value in a 2x3 Matrix for a 4x4 matrix.

Draw-method draws different lines on iOS and Android

I am developing a game in Xamarin and are using Monogame. With the exact same code I get two different results when I play the game on Android and iOS. Here is a picture to compare the two:
The upper line is from iOS and the one under it is from Android. Do anyone know why we get two so different results when we draw the lines with the exact same code? I got a Line class which draws a line, the draw method in the line class is below.
public void Draw (SpriteBatch spritebatch)
{
float angle = (float)Math.Atan2 (PointB.Y - PointA.Y,
PointB.X - PointA.X);
int length = (int)Vector2.Distance (PointA, PointB);
LineRect = new Rectangle ((int)PointA.X,
(int)PointA.Y,
(int)Texture.Width,
(int)Texture.Height);
spritebatch.Draw (Texture,
PointA,
LineRect,
Color,
angle,
Vector2.Zero,
new Vector2 (length, Width),
SpriteEffects.None,
0);
}
If i change the Texture.Width=1 and Texture.Height=2 and width of the line to 3, it works perfectly on both Android and iOS.
But if i want to have a thicker line, and the Texture.Width and Texture.Height is 3 and the width of the line is 12, it works like a charm on Android, but then it gets buggy on iOS.
Texture.Width=2 and Texture.Height = 1 and Width = 13 works on iOS.
So the question is how come something like different Texture.Height, Texture.Width and Width values can bug the line? And doesn't give the same output on iOS and Android when its just XNA?

Drawing text with an MKOverlayRenderer

I'm trying to render text on a map using an MKOverlayRenderer. I have an existing, functional MKOverlayRenderer rendering a set of points, so my only problem is rendering a piece of text for each point within the '-(void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context' function.
All solutions I have found through SO and Google use annotations or UILabels. But I want to have the text drawing code in the same location as the code rendering the points. Also there are about 10,000 points, though I'm ensuring it's not rendering them all at the same time through zoom and bounds checking. I am reasonably sure I don't want to create 10,000 objects with the other solutions.
This is the current test code I have to try to render one of the 'Text Text' items. It is a combination of some of the methods I have found on the net to try to render something.
CGPoint* point = self.pointList.pointArray + pointIndex;
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0);
CGContextSelectFont(context, "Helvetica", 20.f, kCGEncodingFontSpecific);
CGContextSetTextDrawingMode(context, kCGTextFill);
CGAffineTransform xform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
CGContextSetTextMatrix(context, xform);
CGContextShowTextAtPoint(context, point->x, point->y, "Test Text 1", 11);
CGContextShowTextAtPoint(context, 10, 10, "Test Text 2", 11);
CGContextShowText(context, "Test Text 4", 11);
UIFont* font = [UIFont fontWithName:#"Helvetica" size:12.0];
[#"Test Text 3" drawAtPoint:*point withFont:font];
This is my first SO questions, so sorry if it isn't that correct.
Edit: I just saw the text when zoomed in as far as I can go, so realise I haven't been accounting for the zoom scale. Assuming I need to do a scale transform before rendering to account for it. Haven't solved it currently, but I think I am on my way.
I have solved it. Sorry for posting this, but I was at my wit's end and thought I needed help.
The line that rendered was:
CGContextShowTextAtPoint(context, point->x, point->y, "Test Text 1", 11);
Which is a deprecated function, but I don't know any other way to render to a specific context.
To fix it, the affine transform became:
CGAffineTransform xform = CGAffineTransformMake(1.0 / zoomScale, 0.0, 0.0, -1.0 / zoomScale, 0.0, 0.0);
The other error was that the 'select font' call needed to become:
CGContextSelectFont(context, "Helvetica", 12.f, kCGEncodingMacRoman);
I had copied the other encoding from some example code I had seen on the net, but it causes the text to have wrong characters.
If there is still a way I can do it without using the deprecated CGContextShowTextAtPoint function I would still love to know.

How to straighten line endings in Cocos2d?

I'm new to Cocos2d and am trying out some of the basic drawing functions. When I draw a straight line with a high width (50 in this case), the ends of the line are not what I'd expect. What I'd like is for the line to be the same as it would be if I were using CoreGraphics, like this:
however what I see in Cocos2d is this:
The code I'm using to draw the line is in the layer's draw method:
-(void)draw
{
glColor4f(1, 0, 0, 1);
glLineWidth(50);
ccDrawLine(ccp(50, 50), ccp(250, 250));
}
Can anyone tell me how I can get cocos2d to draw a line with the same shape as the green image, rather than the red image?
Try drawing it antialiased.
glColor4f(1, 0, 0, 1);
glLineWidth(50);
glEnable(GL_LINE_SMOOTH);
ccDrawLine(ccp(50, 50), ccp(250, 250));

Resources