0

I'm developing an app. I haven't completed my apprenticeship of Swift 2.2/3.0 and I'm in search of some answers.

First: I am using PaintCode to generate the start of Swift code. I made a drawing with the following properties:

enter image description here

Code Swift:

func drawSpeedView(strokeGap strokeGap: CGFloat = 30, strokeDash: CGFloat = 4, strokePhase: CGFloat = 0, strokeWidth: CGFloat = 31, strokeStartAngle: CGFloat = 225, strokeEndAngle: CGFloat = 315) {
    //// General Declarations
    let context = UIGraphicsGetCurrentContext()

    //// DashedLarge Drawing
    let dashedLargeRect = CGRect(x: 14.5, y: 17.5, width: 291, height: 291)
    let dashedLargePath = UIBezierPath()
    dashedLargePath.addArcWithCenter(CGPoint(x: dashedLargeRect.midX, y: dashedLargeRect.midY), radius: dashedLargeRect.width / 2, startAngle: -strokeStartAngle * CGFloat(M_PI)/180, endAngle: -strokeEndAngle * CGFloat(M_PI)/180, clockwise: true)

    UIColor.blackColor().setStroke()
    dashedLargePath.lineWidth = strokeWidth
    CGContextSaveGState(context)
    CGContextSetLineDash(context, strokePhase, [strokeDash, strokeGap], 2)
    dashedLargePath.stroke()
    CGContextRestoreGState(context)
}

My problem: This code is optimized for iPhone 5. For the proportion of dotted numbers, I need to create a calculation for the value of strokeDash for iPhone 6/6s and 6+/6s+

What I need: I have no knowledge base to mount a circumference calculation yet.

I need a calculation for replace the line:

CGContextSetLineDash(context, strokePhase, [strokeDash, strokeGap], 2)

to replace with a decimal number able to put 12/6/15 dashed around the circle, no matter the perimeter of circle.

Does anyone have a solution to my problem?

Where do I start?

James
  • 1,167
  • 1
  • 13
  • 37

1 Answers1

1

iPhone 5 Issue

As you can see from the line (from your code snippet):

let dashedLargeRect = CGRect(x: 14.5, y: 17.5, width: 291, height: 291)

the drawing space is defined of width 291 points and height 291 points.

Hardcoding these numbers is a bad idea because, as you've noticed, it means that the code would work well only on certain devices and not in others.

To fix this issue you can just grab these resolutions dynamically by declaring the following functions:

func windowHeight() -> CGFloat {
      return UIScreen.mainScreen().applicationFrame.size.height
}

func windowWidth() -> CGFloat {
    return UIScreen.mainScreen().applicationFrame.size.width
}

then you can create dashedLargeRect for example:

let dashedLargeRect = CGRect(x: 14.5, y: 17.5, width: windowWidth()-20, height: windowHeight()-20)

This way you make your code device-agnostic that is always good practice. (please take note that I haven't touched the CGRect "origin", a.k.a. the x,y parameters, consider that your homework :) ).

Second Issue

If I understand correctly, you want to know how to draw that dashed arc.

The secret lays on the line

dashedLargePath.addArcWithCenter(CGPoint(x: dashedLargeRect.midX, y: dashedLargeRect.midY), radius: dashedLargeRect.width / 2, startAngle: -strokeStartAngle * CGFloat(M_PI)/180, endAngle: -strokeEndAngle * CGFloat(M_PI)/180, clockwise: true)

You can see the addArcWithCenter documentation here, let me simplify it for you:

let arcCenter = CGPoint(x: dashedLargeRect.midX, y: dashedLargeRect.midY)
let radius = dashedLargeRect.width / 2
let startAngle = -strokeStartAngle * CGFloat(M_PI)/180
let endAngle = -strokeEndAngle * CGFloat(M_PI)/180

dashedLargePath.addArcWithCenter(arcCenter, 
                                 radius: radius, 
                                 startAngle: startAngle, 
                                 endAngle: endAngle, 
                                 clockwise: true)

now it should be much clearer what this code does, in case that you would like to draw another line over this one (for example to display the car speed, wind speed, air pressure, etc) all you have to do is call a similar function with a smaller/bigger radius and, probably, a different line style (a.k.a. change the CGContextSetLineDash, dashedLargePath.lineWidth, and UIColor.blackColor().setStroke() lines).

Community
  • 1
  • 1
Federico Zanetello
  • 3,321
  • 1
  • 25
  • 22
  • This is of great help to me. I'm sure I will use in my code. However, updated the question to be even more clear. I need a calculation for replace the line: CGContextSetLineDash(context, strokePhase, [strokeDash, strokeGap], 2) to replace with a decimal number able to put 12/6/15 dashed around the circle, no matter the perimeter of circle. It's possible? – James Jul 19 '16 at 17:47
  • 1
    So you actually want the text "12/6/15" to be drawn in the arc instead of the dashed line? you should be able to do that by looking at these answers: http://stackoverflow.com/questions/23948258/ios-how-to-draw-text-curving-along-a-uibezierpath http://stackoverflow.com/questions/3841642/curve-text-on-existing-circle – Federico Zanetello Jul 20 '16 at 17:41
  • This is of great help to me! Thank you! – James Jul 21 '16 at 16:52
  • Glad I could help! Cheers :) – Federico Zanetello Jul 21 '16 at 17:02