The drawing software on the iPad is good. I bought a graffiti software from a child. Here is an example.
Canvas2d. h
View plaincopy to clipboardprint?
- # Import <uikit/uikit. h>
- # Import <quartzcore/quartzcore. h>
- @ Interface canvas2d: uiview {
- Nsmutablearray * arraystrokes;
- Uicolor * currentcolor;
- }
- @ Property (retain) nsmutablearray * arraystrokes;
- @ End
# Import <uikit/uikit. h> # import <quartzcore/quartzcore. h> @ interface canvas2d: uiview {nsmutablearray * arraystrokes; uicolor * currentcolor;} @ property (retain) nsmutablearray * arraystrokes; @ end
Canvas2d. m
View plaincopy to clipboardprint?
- # Import "canvas2d. H"
- @ Implementation canvas2d
- @ Synthesize arraystrokes;
- -(ID) initwithframe :( cgrect) Frame
- {
- Self = [Super initwithframe: frame];
- If (Self ){
- // Initialization code
- Self. arraystrokes = [nsmutablearray array];
- }
- Return self;
- }
- -(ID) initwithcoder :( nscoder *) adecoder {
- If (Self = [Super initwithcoder: adecoder]) {
- Self. arraystrokes = [nsmutablearray array];
- }
- Return self;
- }
- // Only override drawrect: If you perform custom drawing.
- // An empty implementation adversely affects performance during animation.
- -(Void) drawrect :( cgrect) rect
- {
- // Drawing code
- Cgcontextref context = uigraphicsgetcurrentcontext ();
- Cgcontextsetlinewidth (context, 2.0 );
- Cgcolorspaceref colorspace = cgcolorspacecreatedevicergb ();
- Cgfloat components [] = {0.0, 0.0, 1.0, 1.0 };
- Cgcolorref color = cgcolorcreate (colorspace, components );
- Cgcontextsetstrokecolorwithcolor (context, color );
- Cgcontextmovetopoint (context, 0, 0 );
- Cgcontextaddlinetopoint (context, 300,400 );
- Cgcontextstrokepath (context );
- Cgcolorspacerelstrap (colorspace );
- Cgcolorrelease (color );
- If (self. arraystrokes)
- {
- Int arraynum = 0;
- // Each iteration draw a stroke
- // Line segments within a single stroke (PATH) has the same color and line width
- For (nsdictionary * dictstroke in self. arraystrokes)
- {
- Nsarray * arraypointsinstroke = [dictstroke objectforkey: @ "points"];
- Uicolor * color = [dictstroke objectforkey: @ "color"];
- Float size = [[dictstroke objectforkey: @ "size"] floatvalue];
- [Color set]; // equivalent to both setfill and setstroke
- // Draw the stroke, line by line, with rounded Joints
- Uibezierpath * pathlines = [uibezierpath bezierpath];
- Cgpoint pointstart = cgpointfromstring ([arraypointsinstroke objectatindex: 0]);
- [Pathlines movetopoint: pointstart];
- For (INT I = 0; I <(arraypointsinstroke. Count-1); I ++)
- {
- Cgpoint pointnext = cgpointfromstring ([arraypointsinstroke objectatindex: I + 1]);
- [Pathlines addlinetopoint: pointnext];
- }
- Pathlines. linewidth = size;
- Pathlines. linejoinstyle = kcglinejoinround;
- Pathlines. linecapstyle = kcglinecapround;
- [Pathlines stroke];
- Arraynum ++;
- }
- }
- }
- // Start new dictionary for each touch, with points and color
- -(Void) touchesbegan :( nsset *) touches withevent :( uievent *) event
- {
- Nsmutablearray * arraypointsinstroke = [nsmutablearray array];
- Nsmutabledictionary * dictstroke = [nsmutabledictionary dictionary];
- [Dictstroke setobject: arraypointsinstroke forkey: @ "points"];
- [Dictstroke setobject: [uicolor blackcolor] forkey: @ "color"];
- [Dictstroke setobject: [nsnumber numberwithfloat: 5] forkey: @ "size"];
- Cgpoint point = [[touches anyobject] locationinview: Self];
- [Arraypointsinstroke addobject: nsstringfromcgpoint (point)];
- [Self. arraystrokes addobject: dictstroke];
- }
- // Add each point to points Array
- -(Void) touchesmoved :( nsset *) touches withevent :( uievent *) event
- {
- Cgpoint point = [[touches anyobject] locationinview: Self];
- Cgpoint prevpoint = [[touches anyobject] previuslocationinview: Self];
- Nsmutablearray * arraypointsinstroke = [[self. arraystrokes lastobject] objectforkey: @ "points"];
- [Arraypointsinstroke addobject: nsstringfromcgpoint (point)];
- Cgrect recttoredraw = cgrectmake (\
- (Prevpoint. x> point. X )? Point. X: prevpoint. X)-5 ,\
- (Prevpoint. Y> point. Y )? Point. Y: prevpoint. Y)-5 ,\
- FABS (point. x-prevPoint.x) + 2*5 ,\
- FABS (point. y-prevPoint.y) + 2*5 \
- );
- [Self setneedsdisplayinrect: recttoredraw];
- }
- // Send over new trace when the touch ends
- -(Void) touchesended :( nsset *) touches withevent :( uievent *) event
- {
- }
- -(Void) dealloc
- {
- [Arraystrokes release];
- [Super dealloc];
- }
- @ End
# Import "canvas2d. H "@ implementation canvas2d @ synthesize arraystrokes;-(ID) initwithframe :( cgrect) frame {self = [Super initwithframe: frame]; If (Self) {// initialization codeself. arraystrokes = [nsmutablearray array];} return self;}-(ID) initwithcoder :( nscoder *) adecoder {If (Self = [Super initwithcoder: adecoder]) {self. arraystrokes = [nsmutablearray array];} return self;} // only override draw Rect: If you perform custom drawing. // an empty implementation adversely affects performance during animation. -(void) drawrect :( cgrect) rect {// drawing codecgcontextref context = uigraphicsgetcurrentcontext (); cgcontextsetlinewidth (context, 2.0); cgcolorspaceref colorspace = trim (); cgfloat components [] = {0.0, 0.0, 1.0, 1.0}; cgcolorref color = cgcolorcreate (colorspace, compone ETS); cgcontextsetstrokecolorwithcolor (context, color); cgcontextmovetopoint (context, 0, 0); cgcontextaddlinetopoint (context, 300,400); cgcontextstrokepath (context); cgcolorspacerel.pdf (colorspace ); cgcolorrelease (color); If (self. arraystrokes) {int arraynum = 0; // each iteration draw a stroke // line segments within a single stroke (PATH) has the same color and line widthfor (nsdictionary * dictstroke in Self. arraystrokes) {nsarray * arraypointsinstroke = [dictstroke objectforkey: @ "points"]; uicolor * color = [dictstroke objectforkey: @ "color"]; float size = [[dictstroke objectforkey: @ "size"] floatvalue]; [color set]; // equivalent to both setfill and setstroke // draw the stroke, line by line, with rounded jointsuibezierpath * pathlines = [uibezierpath bezierpath]; cgpoint pointstart = cgpointfromstring ([ar Raypointsinstroke objectatindex: 0]); [pathlines movetopoint: pointstart]; for (INT I = 0; I <(arraypointsinstroke. count-1); I ++) {cgpoint pointnext = cgpointfromstring ([arraypointsinstroke objectatindex: I + 1]); [pathlines addlinetopoint: pointnext];} pathlines. linewidth = size; pathlines. linejoinstyle = kcglinejoinround; pathlines. linecapstyle = kcglinecapround; [pathlines stroke]; arraynum ++ ;}}// start n EW dictionary for each touch, with points and color-(void) touchesbegan :( nsset *) touches withevent :( uievent *) event {nsmutablearray * arraypointsinstroke = [nsmutablearray array]; optional * dictstroke = [nsmutabledictionary dictionary]; [dictstroke setobject: arraypointsinstroke forkey: @ "points"]; [dictstroke setobject: [uicolor blackcolor] forkey: @ "color"]; [dictstroke setobject: [nsnumber n Umberwithfloat: 5] forkey: @ "size"]; cgpoint point = [[touches anyobject] locationinview: Self]; [arraypointsinstroke addobject: nsstringfromcgpoint (point)]; [self. arraystrokes addobject: dictstroke];} // Add each point to points array-(void) touchesmoved :( nsset *) touches withevent :( uievent *) event {cgpoint point = [[touches anyobject] locationinview: Self]; cgpoint prevpoint = [[touches anyobject] previou Slocationinview: Self]; nsmutablearray * arraypointsinstroke = [[self. arraystrokes lastobject] objectforkey: @ "points"]; [arraypointsinstroke addobject: nsstringfromcgpoint (point)]; cgrect recttoredraw = cgrectmake (\ (prevpoint. x> point. x )? Point. X: prevpoint. X)-5, \ (prevpoint. Y> point. Y )? Point. y: prevpoint. y)-5, \ FABS (point. x-prevPoint.x) + 2*5, \ FABS (point. y-prevPoint.y) + 2*5 \); [self setneedsdisplayinrect: recttoredraw];} // send over new trace when the touch ends-(void) touchesended :( nsset *) touches withevent :( uievent *) event {}-(void) dealloc {[arraystrokes release]; [Super dealloc];} @ end
Remember to add quartzcore. Framework
Usage: Associate view with canvas2d in XIB