The long discussion on is Code an Art or a Science will continue for years to come because there will always be two sides to it and I am not attempting to join or fuel that discussion. However, I feel that in my lifetime I have been lucky to get exposure to a whole lot of technologies and development techniques over the past couple of decades. With that as a benchmark, I can say that Swift makes development a breeze and also in many ways turns your code into Art.
In this article, we are looking at using Swift for Drawing, not the one with oils and canvases, but drawing lines and curves. This can grow into a better library but for now it is about how code can look better and perform better too.
What are we trying to achieve
We are trying to create code to help us create a path which we can use as we would want. Generating the path is not difficult, but you will see that it makes it easy to use. Lets look at what it would look like,
let path = Bezier()
.moveTo(x:10, y: 10)
.lineTo(x:10, y: 110)
.lineTo(x:60, y: 60)
.lineTo(x:10, y: 10)
.closePath()
.circle(x:25, y: 60, radius: 120)
Note: The syntax shown above is what is required by Swift 3.0, where you need to specify the first parameter.
this will result in a path that creates a triangle and a circle outside of it. which looks something like this.
Creating the Interface
Let’s start with creating a Bezier Class and add the interface that provides you with a facility to use code as illustrated above.
class Bezier {
private var path = UIBezierPath()
}
We start with a private variable that will hold the UIBezierPath which we shall use to draw as required. This is private because we don’t want to allow modification access to it from outside of the class.
next let’s add the interface to access the path, with BezierPaths, it is not the path itself that you can use directly but the cgPath property. so let’s create a property called cgPath, that returns the cgPath from the path variable.
var cgPath: CGPath {
return path.CGPath
}
Writing the functions
We also need to create the four functions : moveTo, lineTo, close and circle . These all take parameters as CGFloat .
func moveTo(x: CGFloat, y: CGFloat) {
path.moveToPoint(CGPointMake(x, y))
}
This function simply is a wrapper to the moveToPoint method that is available on UIBezierPath object. We create the other function wrappers for lineTo, close and circle as follows
func lineTo(x: CGFloat, y: CGFloat) {
path.addLineToPoint(CGPointMake(x, y))
}
func closePath() {
path.closePath()
}
func circle(x: CGFloat, y: CGFloat, radius: CGFloat) {
let frame = CGRectMake(x - (radius/2), y - (radius/2) , radius, radius)
let _path = UIBezierPath(ovalInRect: frame)
path.appendPath(_path)
}
With the circle function, it is easier to simply use the ovalInRect that creates a frame and creates a path inside of that frame.
Chaining the functions
The only thing that remains is that the functions cannot be chained, it is called a fluent interface. In the simplest implementation all you need to do is return the same object for each function call.
func moveTo(x: CGFloat, y: CGFloat) -> Bezier {
path.moveToPoint(CGPointMake(x, y))
return self
}
That’s all you need, you can repeat the same for the other functions, return a Bezier object, that returns self at the end of each function.
There you have it, a simplistic way to create simple Bezier Paths vectors using moveTo and lineTo functions. If you want, you could also have a line function that uses relative dimensions instead of absolute points.
In Closing
While everyone enjoys a particular style of coding, I prefer the easy to read and simplistic approach to code. Something that can be easily modified or managed further by developers than create a complicated library that developers use but avoid touching for the fear of not understanding magic numbers and macros, etc.
It is just a matter of time when Swift will be everywhere and if you want to get future generations onto Swift, then it is on you to write simplistic code.
Views All Time
1492
Views Today
1