- Download demo project - Does not exist due to Apple licensing, but it's easy
to build with the source.
- Download source - 163 KB
Introduction
This class is essentially the code from my iOS app: AKW Factor Tree. It allows users to do rough (math) work on the device instead of using paper. The class provides all the functionality that you see in the image: color change, undo/redo, clear, dragging/sizing, replay the touches, and hiding/showing the scratchpad. As mentioned in the title, this class uses GLKit which is only available for iOS 5.0 and up.
The idea for this class comes from GLPaint which is provided by Apple. However, all the code is original because the functionality is quite different: OpenGL is meant for the whole screen and I needed a partial screen solution. So I created a solution with GLKit. Why am I providing this code? The iOS learning curve is quite steep if you are creating a releasable app and it would have taken me significantly more time to release my app if not for the active on-line community providing solutions and tutorials to the many hurdles that I had to cross (much of my help came from StackOverflow; Ray Wenderlich's website was also useful). So I am giving back to the community by providing this code.
The only big feature this class does not provide is screen rotations. However, it is a simple matter of setting 2 variables and calling the draw routine.
This class is meant to be a scratchpad, but you could easily convert it to painting or drawing; there are plenty of tutorials kicking around for this. Another feature that you might want is to save all the draw data. This would be simple to add since it is all stored in arrays and you can serialize this in your own format.
Another simple feature to add would be adjusting the replay speed. I didn't add this because it would just clutter the interface. Of course there are more features that you can think up, but you must decide whether you want something easy to use or give more options to the user!
Using the code
I don't use IB much because I like to do things programmatically. So, it should come as no surprise that this class is best utilized programmatically (in the demo,
I did hook it up with IB). In your UIView, you need to declare the scratchpad (in the demo, it is AppDelegate.h):
#import "ScratchPadView.h"
...
@property (nonatomic, retain) ScratchPadView *spv;
...
Next in your UIView (in the demo, it is AppDelegate.m), you need to release the scratchpad in the dealloc
method:
...
self.spv = nil;
...
In your UIView initialization (in the demo, it is application:didFinishLaunchingWithOptions:
), add:
...
ScratchPadView *s = [[ScratchPadView alloc] init];
self.spv = s;
[s release];
[self.viewController showScratchPad:nil];
...
Finally in your UI handler (in the demo, it is ViewController.m. Because I used IB for the demo, the code below is different than the code in the project), add to your show scratchpad button:
if ([self.spv superview] == nil) {
[self addSubview:self.spv];
[self.spv scaleScratchUp];
}
Using the code - Customizing
The basic things that you might want to adjust are the buffer sizes. The default is 3000 line segments and 300 lines; you will find these in
ScratchPadView.h. Note that when either buffer is full, an alert will be displayed to the user requesting if they want to clear the scratchpad.
You can decipher most of the code by looking Apple documentation on the variables and methods that are being used. If you are a beginner, you may not be aware that overriding a view's drawInRect
or drawRect
will use your code to do custom drawing. So if you wish to change the sketchpad's pen drawing to painting glkView:drawInRect:
is the piece of code you want to modify.
glkView:drawInRect:
works by clearing the screen, then drawing all the lines. You might think that this is inefficient, but it actually runs quite quickly. I was looking for some way to access the back buffer to just update it with the last line segment, but this was unnecessary.
The iPhone screen real estate is small, but if you really want to make the scratchpad draggable and sizable, then you will want to modify adjustNumPad
by taking out the code that is !largeFormat
.
If you want to modify the code to change how quickly the replay mode draws, look at replayInt
. Note that touching the draw surface will cancel replay mode.
I'm not sure that you will need to modify the other pieces of code, but if you have any questions, feel free to ask!
Points of Interest
In addition to GLPaint, I looked at SimplePaint by Cesar Manuel Pinto Castillo. It wasn't quite what I needed, but it did help my learning process. So I give kudos to Cesar! You can find his code on github under Simple-Paint-App-iOS.
Before GLKit, I attempted to use QuartzCore, but the performance wasn't very good. There was considerable lag with the touches to drawing. I was looking for a way to draw directly onto the back buffer rather than copying the back buffer and drawing on the copy. It was particularly slow when the scratchpad was larger.
History
- November 2012 - Version 1.0