I just want to create line graph within lines and dashed lines. I don't know how to setup the layer(CAShapeLayer) or path(UIBezierPath) able to create both of these lines in the same layer. Can you give me any opinions? Thank you very much.
-
If you want a good answer you should try to solve the problem yourself. If you don't manage to solve it, come back, tell us what you've tried and why it hasn't worked and we can help you figure it out. – EmilioPelaez Jan 31 '17 at 04:45
-
sublayers are needed for this kind of implementation Refer: https://www.raywenderlich.com/2502/calayers-tutorial-for-ios-introduction-to-calayers-tutorial – Md. Ibrahim Hassan Jan 31 '17 at 05:32
-
Do not use CAShapeLayer at all. If you do, as you have already said, you will need many of them, and you prefer not to do that. Instead, just use UIBezierPath to draw all the different lines of the graph into one view. – matt Jan 31 '17 at 19:52
3 Answers
I don't think you can with a standard shape layer. I believe you'll need 2 separate shape layers.

- 128,072
- 22
- 173
- 272
-
-
is it possible if I create a subclass of standard shape layer? – phu the cong phu thecong Jan 31 '17 at 15:13
-
It should be, but I've never tried to subclass `CAShapeLayer` before. – Duncan C Jan 31 '17 at 18:58
I'm not sure if i understand your question. You have CAShapeLayer or UIBezierPath and you want to be able to draw a dashed line and continue line using same object?
If you want to obtain something like this using a single UIBezierPath, it is possible. The answer is a little longer, and is necessary some explanations, so i will answer you if this it what you want to do.
Edited answer
The solution is a required a little messy code, but in some cases it works very well so:
- We will use UIBezierPath to achieve that line.
- We also need a way to be able to get the length of the bezier. For that purpose, exist UIBezierPath-Length extension. Unfortunately is written in Objective-C so, if you don't have a Bridging-Header for your app, is time to create one. (Let me know if you need help with that)
Now, 'cause we know the length of any shape we can move forward and check apple documentation regarding Line Dash style. I'm a lazy person, so I will not copy/paste from documentation, I prefer a snapshot. (it's faster)
Now all is remain to do is to apply that to our path. To be more easily to explain we will take an example:
We want to create line from the first image. The path for line is stored in var graphLine:UIBezierPath. We use the extension to get the length of graph line. Let's say the length is 40. I assume that you will work with percents. The line must be 50% continue and the rest of it, dashed. So we will divide the 40 with 100. Now for the hard part, we need to create the array with values that will tell to our path how to be drawn.
First value is easy, our result multiplied by 50. The next values, can be added using a repetitive instruction... in the end our array should look like this :
[20,2,3,2,3,2,3,2,3]
I know the explication is not the best. Blame my english. I hope that the code will be more helpful.
var graphLine = UIBezierPath() // init your bezier line properly
let percentValue = graphLine.length() / CGFloat(100)
var pattern:[CGFloat] = []
var currentLength:CGFloat = 0 // Use that to keep track of the added values to the pattern
//add the first line.
Swift.print(graphLine.length())
pattern.append(percentValue * 50)
currentLength = percentValue * 50
while (currentLength < graphLine.length()) {
pattern.append(percentValue) // this is the length of gap
pattern.append(percentValue * 2) // and this is the length of next line
currentLength += percentValue * 3
}
// now we can set the properties for graphLine
graphLine.lineWidth = 3
graphLine.setLineDash(pattern, count: pattern.count, phase: 0)
UIColor.green.set()
graphLine.stroke()

- 1,801
- 3
- 22
- 41
-
-
As answered above, it's possible to create the graph like this one with sublayers. But my graph is scrollable, I must create a lot sublayers if use this solution. – phu the cong phu thecong Jan 31 '17 at 14:46
-
Thank your for your helps. I tried to subclass CAShapeLayer and use UIBezierPath to draw the lines on this layer. But I can't setup the path(setLineDash) to create both dashed line and line as you suggested – phu the cong phu thecong Feb 01 '17 at 14:17
-
Yesterday I tested the above code, and it work https://dl.dropboxusercontent.com/u/75665703/TestDashedLine.zip – C-Viorel Feb 01 '17 at 14:22
-
Since you use UIBezierPath to draw the line on view not layer, so it works fine. My graph view includes some layers to display other thing. I use one of them to draw the lines on. Anyway I'll try to draw the lines on view. Thank you again. – phu the cong phu thecong Feb 02 '17 at 02:22
-
You can use CAShapeLayer. The only difference is that how you pass it the pattern array. https://dl.dropboxusercontent.com/u/75665703/TestDashedLine2.zip – C-Viorel Feb 02 '17 at 07:10
-
This solution is the best. You saved my life thank u. I managed to use it for only 6 dashes in a progress bar with dynamic size. – Kawe Mar 03 '20 at 19:14
You can't use a single shape layer. You can use more layers as mentioned before, or implement your own shape layer class which supports more than one bezier path. I postet a simple implementation for a custom shape layer some weeks before (https://stackoverflow.com/a/41137463/6319106). You can use it as a basis for an appropriate implementation.