Objective-C iPhone Programming Lesson 10 - Drawing with CoreGraphics
Hey guys, this is Matt. Heads in on one with our Kent iPhone programming tutorial. In this video, I'm going to be showing you how to use Core Graphics to draw graphics on the screen. By draw, I don't mean have the user move their finger around; I mean you, as a programmer, draw shapes on the screen. So it's not quite as exciting, but it's still pretty cool.
I'm gonna go into Xcode, say file, new project, and I'm gonna go to application, view based application. I will call it Core Graphics Testing. Alright, so the thing you have to understand with Core Graphics is that you can draw Core Graphics instructions basically on a CG context. In order to have one of those, for now, we're going to be sub-classing UIView.
What you want to do, in order to be able to use Core Graphics, is right-click on classes, say add new file, go to Cocoa Touch Class, Objective-C class, and make it a subclass of a UI view. Make sure your UIView is checked there. Alright, next I will call it DrawView.
Now, what you want to do, since we created this UIView which we can draw on, is hook it up with Interface Builder. So we're gonna open our Interface Builder XIB. Alright, the next thing you're gonna want to do is click on the contents of our view controller, which is a UIView. Go into our view, identity, click on this little I, and type class. When we're typing our class, we're gonna write DrawView because that's the class we just created, and it should auto-suggest that for you. If it doesn't, there's probably something wrong.
Alright, so go up and save this and then quit Interface Builder. Now in DrawView, you're going to want to uncomment the drawRect function by removing the slash star and star slash. Right in the DrawView is where we can write our actual Core Graphics code. This is where you're going to be putting Core Graphics instructions and dealing with the graphics context.
So the first thing you want to do to interact with Core Graphics is declare a graphics context. In order to do that, you want to write CGContextRef context = UIGraphicsGetCurrentContext();
. Alright, and now we have an instance of a CGContextRef which we can deal with.
So the first thing you want to do in drawRect is clear the context. So we're gonna write CGContextClearRect(context, self.bounds);
. All you have to really know about bounds is that on any UIView, there's an item or a member called the bounds, which is basically a rectangle with the coordinates (0, 0) in the size of the view. So it's not the frame because you can have non-zero coordinates, but it is the size.
So use it when you want to add a subview that fills a view or clear the whole rectangle in this case. Alright, so if we run this, and I'll set it to the iPhone simulator, when it runs, you'll basically see a blank screen, which will be black even once the application's loaded, and that means that we've cleared the context successfully.
Let's see. As you can see, it's a black screen; the application is definitely loaded. Alright, so now what we're gonna do is actually draw some stuff. So we're gonna start out by using colors, and in order to do this, we're going to declare a color. We're gonna say CGColorRef blackColor = CGColorCreate(colorSpace, ...);
. Or I’ll make a black color. Black is pretty boring; I'll make a yellow color.
CGColorRef yellow = UIColor.yellowColor.CGColor;
. And basically, UIColor is the UIKit class for colors. Now we're not dealing with UIKit; UIKit is for things like text fields and checkboxes in views. We're using Core Graphics, which is more C-based, and in order to do that, we have to convert a UIColor (which is in this case UIColor.yellowColor) into a Core Graphics color, and that's why I'm calling CGColor
. It returns an instance of CGColorRef.
So now we've got our yellow color. Now what we're gonna do is write CGContextSetFillColor(context, yellow);
. And we're gonna do that with a color, so set fill color context, and the color will be yellow. Alright, next we're gonna draw a rectangle.
So I'll do CGContextFillRect(context,CGRectMake(10, 10, 100, 100));
. And CGRectMake
is basically a function where you pass the X, Y, width, and height to it, and it returns a CGRect structure with that information already set. So this is going to fill a rectangle at the coordinates (10, 10) with the width and height of 100.
So if we run this, you'll see a yellow square. And as you can see, there's a yellow square. Alright, so now what we're gonna do is draw an ellipse which is a circle. I'll say CGColorRef redColor = UIColor.redColor.CGColor;
. And as you see, just as I did it with the yellow, I did it with the red, and there are already a bunch of predefined methods for a bunch of different colors like yellow, red, etc., on UIColor.
So it's super easy to do that. Basically, we're gonna copy this code and change it to CGContextFillEllipseInRect(context,CGRectMake(...));
. I'm gonna type it out because we already have our parameters, and I’ll give it random coordinates. I'll just give it those, and I'll make it 120 by 120 just to make it a circle, not an ellipse.
And you're gonna see a yellow circle now. It says unused color red because we forgot to change this to red. Now, when I run it, you'll hopefully see a red circle instead. As you can see, there is a red circle there. So basically, that's how to do predefined shapes like ellipses and squares.
But let's say you want to do a triangle or a shape with many polygons. There's something called a path, and you can use these paths to make any shape. So I'm gonna show you how to use a path to make a triangle. So, as you know, a triangle has three points. For instance, here, here, and here would be an example, and those points represent vertices of the triangle.
So we're basically going to be specifying the vertices of a triangle and drawing them. So in order to do that, you're gonna write, I'll just make a comment "draw a triangle." CGContextBeginPath(context);
and that's basically telling our context that we are about to give it some coordinates of vertices and lines and such.
After we're done all that, we're gonna write CGContextClosePath(context);
which will close off our path, and in here we're gonna write our code to give vertices. I'll say CGContextMoveToPoint(context, 150, 110);
. Then I'll draw a line, so I'll say CGContextAddLineToPoint(context, 200, 110);
and I'll do one more CGContextAddLineToPoint(context, 200, 160);
.
Now here we'll have our entire context specified. Now we need to fill the path, so write CGContextFillPath(context);
and it'll use the last fill color we specified, which was red. Alright, and you'll see a red triangle right there.
Now we're gonna move that around a little bit just to make it look a little more you and less organized, I suppose, but you know, cleaner. We can change these points if we want to move it around. I won't even bother moving around for now because it's just an example.
We can also set a different fill color, so how about CGContextSetFillColor(context, red);
. I'm giving it our red color again, and now we should see, oh, not red color, just red, sorry. And we should see that it's still red because we gave it a color. Now we can create a new color for the triangle or make a new color rest.
I'll make it blue: CGColorRef blue = UIColor.blueColor.CGColor;
. You can also make your own UI colors. I mentioned that in a different video. That’s yeah. No specify a blue triangle. If we run this, our triangle is blue, as you can see.
So that's basically a couple of shapes you can do. More extravagant shapes can be chosen with different points. You can also use CGContextAddEllipseToPath()
and this is the kind of thing that, for instance, Lasso Capture uses too. When you're dragging around, it uses a path, adds all the points to a path, and strokes the path, which I'll show you in a second.
Here's how to draw, say, a curvy line. I'll just call it drawCurve
, and I'll move it to a random point. How about (10, 300). I'll add a line to (10, 320) and I'll make it (12, 320). I'll add another point to (14, 315). This isn't a very good curve just because it's gonna be teeny and it's gonna be really stretched out.
So maybe I'll make it (30, 21)—how about (30, 20)—but, you know, it's not gonna be a very obvious curve. I'll make this actually (40, 20)—but, you know, it's not gonna be a good curve. We don't even have to close the path because that'll just cause problems.
And here we'll set stroke color, and I'll make it yellow. I'll call CGContextStrokePath(context);
. And, there we go! We don't need this at all because, you know, we don't need to close the path because it's not a shape.
As you can see, there’s our squiggle. It's very small, but obviously, you can do different things. Maybe I'll make a tutorial in the future just to draw a sine curve or something like that. But basically, you guys can see from this how to draw a bunch of lines.
I'll make these points a little bigger. We’ll make, how about we go to (120, 400) and then I’ll go to (300, 200). This will look awful probably, but as you can see, it drew a little line.
So what they do—that’s pretty much how to use Core Graphics to draw. I'll have a link in the description to download this sample code because I bet a lot of you probably don't want to have to copy all this down, and maybe you want to reuse some of this code in the future.
But anyway, that’s Core Graphics! Basically, that's how to draw on a view using Core Graphics. In a few tutorials from now after I teach you file I/O, we'll be making our own file format where you can specify the front shapes and draw different shapes and lines and such. So that'll be cool.
Anyway, thanks for watching, Mac Heads, or the one. Subscribe and you're bye!