Core Graphics Tutorial Part 1: Getting Started

Ok, I think I know now. In part 2 of this tutorial you say “In the Document Outline, drag the Counter View to make it a subview of the yellow view, and make sure it’s positioned behind its sibling Graph View.” I guess that’s how.

@rockhammer - I only meant that when you drag the view in Interface Builder, make sure the hierarchy is such that the UILabel is a subview of the Counter View. Sometimes you need to check this - my hierarchies get borked often.

This is a great tutorial. I am definitely going to take the other tutorials in this series. I think I’m also going to need to sign up for a paid subscription so I can watch your videos. I bet I will learn a lot. You do a good job of clearly presenting these topics.

I have a question. I want to create an iOS app to help learn note reading on a guitar. I want to randomly pop up a note on the musical staff. I will then play that note. After I play it, the app will show me what string and fret I should have used. It would then pick another random note. I may also try to get the app to listen for the note and determine if I played the correct note.

My app is simple because I would draw only one note at a time. And the notes could all be quarter notes. I am not concerned about the length of time the note is played, only that the correct note is played. So my problem is only to draw a quarter note at the right place on the staff. And with an optional sharp or flat symbol.

I’ve tried to find a library of bezier path commands for notes, but there doesn’t seem to be anything so I’ll need to create my own library. I also wonder if it might be possible to use some type of musical font.

Do you think bezier paths are a good way to do this? Can you think of other alternative methods?

1 Like

@clarks - thank you for that - there are a lot of good videos available - I’ve only contributed a few of them. But well worth a look to see what’s there!

Your idea sounds like a good one.

Either creating a bezier path or using a font should work. I would incline towards creating a path using PaintCode, and possibly at the start of the app creating a global image from that path to suit the size of the screen. (The image would be slightly easier to use than drawing each time, as long as you don’t need to change the size during the app.) If you don’t have PaintCode, you could experiment with creating the note in a vector program like Illustrator and exporting a pdf and using that as the image asset. Some people have said it looks fuzzy, but I’ve had good success with that.

Hey Caroline, you might be surprised, but I am following this tutorial using Xcode 8 beta 6/Swift 3, and having absolutely NO problem keeping up! I just type or copy the code and let Xcode suggest changes; it works like a charm!

This is one of the BEST tutorials I have found on Core Graphics, and thank you for the awesome work! :grinning:

1 Like

That’s lovely of you to say so! Thank you :smiley:

I just tried to compile run the demo, after fixing a bunch of “Swift 3 changes”, and got a SIGABORT, saying (I think) that the selector “btnPushButton” wasn’t known to the view controller
 Which seems a bit odd. It also have me a warning about the line “func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) → Bool {” saying:

“Instance method ‘application(application: didFinishLaunchingWithOptions:)’ nearly matches optional requirement ‘application( _: didFinishLaunchingWithOptions:)’ of protocol UIApplicationDelegate”

The two Fix-it’s are:

  1. Make [
] private to silence this warning
  2. Add ‘@nonobjc’ to silence this warning

Neither one seems to work, nor does deleting the method entirely (then it just doesn’t open).

The really strange thing is, I actually got this tutorial to compile the other day and run on an iPod (6)! I’m running OS 9.3.5, with a personal, non-paid code signing certificate. I might just jailbreak and install Cydia just to be able to (I hope) not have to mess with code signing ever (until I learn enough to justify paying Apple - even a modest $100/year).

Ah, to remember the good ol’ days when you could get THINK Pascal or C, write code, and simply RUN IT! ( [Steve Jobs singing from the grave] “Welcome to my walled garden
 We are a hardware company, but you don’t really own it
”)

@jimw338 - There is a trick to converting to Swift 3 really easily. However, I don’t know whether it works with the non-paid code signing certificate. If you have a team, then it should.

  1. Download the project from the tutorial again to make sure it’s clean.

  2. Open the project and when it asks if you want to convert, click Later twice.

  3. Go to your Build Target’s General properties and put in your team (hopefully from the drop-down list).

  4. Quit Xcode

  5. Restart Xcode and open the project.

  6. This time, click Convert and do the conversion.

Your project should build and run without any further changes.

There is still that compile warning in AppDelegate, so change the method to private to get rid of that warning.

Yeah, that worked. I guess that it won’t convert everything

Ok
 I’ve got a new problem. :slight_smile: (Other than the fact that the constraint system in IB doesn’t make sense - I have to drag vertically to set a horizontal constraint between the button and the view?) I’ve set up the CounterView which simply calls UIRectFill so I can see it in the Storyboard.

But IB doesn’t show the fillColor @IBInspectable property for the CounterView object. It shows the custom properties for PushButtonView though. Is this an xCode bug (or something strange with my xCode?), or is there something else wrong?

My project is on my git, here:

Thanks,

You can set font sizes for different schemes in the Preferences. But can I set a different size for Print and Display? Small thing, but
 Or do I have to figure out how to write xCode extension and/or swizzle methods? (Or just get AppCode)

If it’s that your color doesn’t change when you use that popup with all the colors, then sometimes that doesn’t work. Try clicking the thing at the side of the control (<>) and using one of the colors off that. It should work.

To get the sliders to work, sometimes you have to click the Counter Fill color box several times to get it to recognise that you’re changing color.

(It works for me)

You mean in the debug console? No idea!

Hello, I managed to do the first part of this tutorial, fixing things along the way for Swift 3. But one small problem – there is no vertical space between the top of the screen and the first control. The three controls are not centered on the screen vertically – they start at the very top, leaving all the white space at the bottom. Is there some constraint reason for that?

Actually, it looks like since the middle button is centered vertically, then that leaves equal space for the meter on top and the red button on bottom. But the top meter is so much larger that it reaches the top of the screen, at least on an iPhone 7 simulator. How would I tell it to center the whole group of three controls vertically so that there was equal space at the top and bottom of the screen? What device are you using in your demo that makes it look correct?

@bsabiston - I just downloaded the final sample code from the end of part one and converted it to Swift 3.

If you have trouble converting, do this. Download the sample code again. On first open, don’t convert, but click Later twice. In Project Settings, change your target development team and quit the project. Then reopen the project and convert. Mine then converted cleanly without any changes.

You should then be able to see the auto layout I’ve used in the storyboard.

hey! thanks for the great tutorial! Im trying to make the following UI: Drivar – Drive Augmented Reality
Im stuck trying to get the circle itself to change size. Tried to change and create a circle as follows but it seems to entirely reposition the UI view on the phone to the top left and ignores the constraints.
center = CGPoint(x: rect.width/2, y: rect.height/2) var path2 = UIBezierPath(arcCenter: center, radius: 100, startAngle: 0, endAngle: 360, clockwise: true)
Any help is much appreciated.

@allenwixted - I don’t have enough information, I’m afraid. Core Graphics doesn’t use constraints. UIViews do. You use Core Graphics to draw the bitmap that the view will display.

@caroline apologies, here’s a screenshot comparing my code with one section commented out and in to show the difference. Perhaps my terminology is misinformed. I was expecting the code from lines 28 on to draw a green circle in the middle of the screen and not move the whole UIView to the top left.

Seems like a lot of work for one, very simple-looking button. Why wouldn’t you just want to draw it (or maybe you personally do, and this was just intended for informative purposes)?

I think there is some confusion about UIViews vs what Core Graphics does here?

rect as passed to draw(_:) is the view’s bounds. If your view is 100x100 then rect will be (0,0,100,100).

You change center in the method (not a good place to do it). Changing center will move the UIView, but here you’re not changing anything, because center is already at (bounds.width/2, bounds.height/2).

draw(_:) is just for drawing code, such as fills and strokes of paths. You shouldn’t be repositioning the view inside it. Your view controller is a good place to reposition views.