Group Group Group Group Group Group Group Group Group

raywenderlich.com Forums

Apple Pencil Tutorial: Getting Started

In this Apple Pencil tutorial, you'll learn about force, touch coalescing, altitude, and azimuth, to add realistic lines and shading to a drawing app.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1407-apple-pencil-tutorial-getting-started
1 Like

Hi, Caroline,

This was a really nice tutorial, and it reminds me I’m still interested in this one part:

you had to do complex things like convert your strokes to spline curves to make drawings look decent

I’d really like to know how to do that, especially to make a blek style line, or one that let’s say thickens and burns as the swipe happens, and thins out towards its constantly moving tail…

even though the coalescing touches added a bit of resolution, i could still see those straight lines between points that I’d prefer to be curved.

You’ll need to get familiar with Bezier curves.
This is the best article I’ve found on drawing splines and varying width dependent on velocity:

There’s also a drawing tutorial here:


which shows how to go from shaky writing to smooth writing.

This is a good article on Bezier curves:
http://ronnqvi.st/thinking-like-a-bzier-path/
but there’s a ton more articles out there on Bezier curves.

1 Like

Thanks for the interesting links!

So sad that it’s all in objective C :frowning:

luckily i know about bezier paths and control points… i just need to understand the syntax of handling the array of touches that is built and used to draw the chunks of line…

I guess I’ll play with that tutorial and see if swiftify.co is helpful :slight_smile:

I didn’t know about swiftify.co. What a great idea! Having said that, in my opinion, it’s a good idea to muddle through Objective C sites because there are a lot of valuable Objective C tutorials and projects out there. And in most cases, it’s a simple translation.

1 Like

that’s a good point… I’m trying not to fill my head with too much C but perhaps a little wouldn’t be horrid. I’m still interested in finding out how to make a blek (app) style line, taking advantage of all the coalescing touches and so forth.

also interesting to me is the audio synth abilities of iOS, especially by making the sounds blek does when drawing…

This is a great tutorial! I am new to Swift/iOS, and am learning a lot.

Was wondering, is there a way to have a background image in this? I tried setting canvasView.image, but obviously that wont work.

Also, the eraser is basically a white pencil - which wont work if there is a background present.

Great job on this tutorial!! :slight_smile:

You can have an image view under the canvas view, and set the canvas view’s background color to clear color.

Yes - I faked the eraser - the tutorial was focussed on using Pencil rather than making a drawing app. But something like this might work:

In drawStroke(_:touch:) before stroking the path at the end:

   if touch.type != .Stylus {
      let color = UIColor(red: 0, green: 0, blue: 0, alpha: 0)
      color.setStroke()
      CGContextSetBlendMode(context, .Clear)
    }

And thanks for the kind words :smile:

1 Like

Hi Caroline!
Thank you so much for your reply. This is amazing - so much to learn! I will be subscribing to your video tutorials shortly!

1 Like

Thank you for your GREAT tutorial.


I'd like the drawn image to stay the same size in both portrait and landscape.

The code works great for when the ContentMode is set to .ScaleToFill.
But if I set the ContentMode to a non-scaled mode like .TopRight and rotate the screen, the image proportions change when touchesMoved is fired. I think it has to do with placing the drawingImage into the context using a bounds that was different from the previous rotation, but I can’t figure out how get it to draw with the correct proportions.

I’ve tried storing and using a previous bounds (before rotation), setting the ContentMode before and after adding the drawingImage to the context, and even looking at manipulating cg/ci Image data using extent, etc…

Any suggestions?

@bleckett - I’ve spent a bit of time with this one. I’m not sure I’ve done it the best way though.

I am assuming you want to do something like this:

That’s where the painted view does not rotate, but any other views do. If you just want to turn off rotation for the whole app, you can do it in the Project Target settings as the Scribble starter project does.

I’ve taken a combination of this:

and this:

https://developer.apple.com/library/content/qa/qa1890/_index.html

I couldn’t get the Apple suggestion to do what I wanted it to do, but removing auto layout from the canvasView and putting it into a xib allowed me to rotate it as per the stackOverflow link.

The attached zip is my suggestion. (I changed eraser color to green for testing on the simulator.)

Scribble-Working Rotation.zip (1.1 MB)

1 Like

Thank you. I didn’t think of using CGAffineTransform!
I did remove auto layout for the canvas view and set the contentMode to topRight (and extended the view so that it covers both landscape and portrait). But was hoping that there was some trick with drawing into the context.

Thank you again.

Hi Caroline,

This is a great tutorial! Thank you so much.

I was wondering how can we save and edit previous drawing.

I used this to save the drawing:

let data = UIImagePNGRepresentation(canvasView.image!)
let userDefaults = UserDefaults.standard
userDefaults.set(data, forKey: “test1”)
userDefaults.synchronize()

And used this to retrieve the files:
if let data = UserDefaults.standard.data(forKey: “test123”),let image = UIImage(data: data,scale:1.0){
canvasView.image = image
}

But when i started to edit retrieve files all drawing has been deleted.

Any tips. Thanks.

Best Regards,

Lyndon

Hi Caroline. I wanted to thank you too for this very valuable tutorial. I had no problems building a swift drawing app as an exercise. I am stuck for now with an Objective-C drawing engine in my main project. I cant seem to find a tutorial as in-depth as yours based in ObjC. Is there a reason for that? I wonder if you point me (semi-pun) in the right direction.

Many thanks!

David

@daviddelmonte - thank you :].

I don’t know of any modern tutorials being written in Objective-C - all tutorial sites that I can think of have moved to Swift.

www.raywenderlich.com has been going for years, so the older tutorials are written in Objective-C and they should come up with Google. Anything dated before June 2014.

For example there’s this Core Graphics drawing series by Ray: https://www.raywenderlich.com/32283/core-graphics-tutorial-lines-rectangles-and-gradients

Edit: The reason for no Objective-C is that Swift is the way forward. There will still be a large code-base of Objective-C apps, but companies are gradually switching to Swift. It’s faster to run (generally) and faster to code (once you know the language).

1 Like

You are right of course. Time to change the engine to a swift based version. I hope the client will go for that. I’ll look through the tute list to see if something will make it easier. I do appreciate you getting back to me…
David

Sorry, another question… You are using a UIImageView as your base class. Was there a reason you do not use UIView? thanks again!

@daviddelmonte - UIImageView is a subclass of UIView, and it draws an image automatically.

1 Like

Hello Caroline. I have tried to implement this in my app, but it is not working as desired.
I am always getting zero value in “touch.force”.
Please help. Thanks…

I’ve downloaded and converted the sample code to Swift 3 and run it on my iPad Pro.

I’ve added this:

print("force: \(touch.force)")

to lineWidthForDrawing(), and it successfully prints out non-zero values.

touch.force will only produce values if you use Apple Pencil on an iPad Pro. Are you doing this? If so, does the sample code work for you?

1 Like