acerbetti / ACEDrawingView

An open source iOS component to create a drawing app
Apache License 2.0
665 stars 171 forks source link

how to save drawing ? #65

Open wangsuikang opened 8 years ago

wangsuikang commented 8 years ago

Hi, I want to save drawing ,when I finish drawing. I can open it again.Please tell me how to do it .Look forward to your reply .Thanks!

acerbetti commented 8 years ago

I think the best way is to apply the protocol NSCoding to each tool, so you can serialize the arrays of steps and apply them again in the future

TripwireNL commented 8 years ago

Can you give an example on how to do this, I can't seem to figure out how to save a drawing. I'm using Realm as a database and I want to save the drawing in Realm so I can reload it, but I'm stuck at implementing the NSCoding protocol in the Pen tool.

acerbetti commented 8 years ago

Try to look here to get some idea https://github.com/mro/MROGeometry/blob/master/MROGeometry/NSCoder_MROCGPath.m

TripwireNL commented 7 years ago

Still don't get how to do this. I've added the NSCoding protocol to the AceDrawingPenTool and tried to implement the example you gave. But I don't know when and where to call the encode feature to save it? Can you provide one example on one of the tools how to implement it please?

acerbetti commented 7 years ago

If you have implemented the NSCoding protocol correctly, saving it should be very easy. Here is a tutorial https://www.raywenderlich.com/1914/nscoding-tutorial-for-ios-how-to-save-your-app-data

TripwireNL commented 7 years ago

Hi acerbetti,

I finally had some time to pick up where I left. I've wrote this code to save the UIBezierPath (As i understand correctly the UIBezierPath adheres to the NSCoding protocol so I didn't add that (just testing to save and load the lines). I've made the pathArray of the AceDrawingView class public so I can access it in my other classes. This is my code as of now but it doesn't work at the moment I see that the data is saved in NSData structure but it's not loading the drawing back.. :


-(NSData *)saveImageAsData {
    NSData *data;
    for (id tool in aceDrawingView.pathArray) {
        if ([tool isKindOfClass:[ACEDrawingPenTool class]]) {
            ACEDrawingPenTool *penTool = (ACEDrawingPenTool *) tool;
            UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:penTool.path];
            data = [NSKeyedArchiver archivedDataWithRootObject:path];
        }
    }
    return data;
}

-(void)loadDrawing:(NSData *) data {
    UIBezierPath *path =  [NSKeyedUnarchiver unarchiveObjectWithData:data];
    CGMutablePathRef cgPath = CGPathCreateMutableCopy(path.CGPath);
    ACEDrawingPenTool *tool = [ACEDrawingPenTool new];
    tool.path = cgPath;
    [aceDrawingView.pathArray addObject:tool];
    [aceDrawingView updateCacheImage:FALSE];
    [aceDrawingView setNeedsDisplay];
}
JinkProject commented 7 years ago

@Tripwire999 That is the same issue I'm having. I am correctly storing and reloading the drawn paths, but when I run the method updateCacheImage:, nothing happens. @acerbetti Could you give some insight on how to achieve this?

TripwireNL commented 7 years ago

@JinkProject Let's say we use the PenTool, I use the following function to load the data back from the NSData we archived with the NSCoding protocol (DrawPathObject is a Realm object):

+(ACEDrawingPenTool *)createPenTool:(DrawPathObject *)drawing {
    UIBezierPath *path = [NSKeyedUnarchiver unarchiveObjectWithData:drawing.drawPath];
    ACEDrawingPenTool *tool = [ACEDrawingPenTool new];
    tool.lineColor = [UIColor colorWithString:drawing.lineColor];
    tool.lineWidth = drawing.lineWidth;
    tool.lineAlpha = drawing.lineAlpha;
    tool.path = CGPathCreateMutableCopy(path.CGPath);
    return tool;
}

And the returned tool is added to the pathArray. After that I just call:


[aceDrawingView updateCacheImage:YES];
[aceDrawingView setNeedsLayout];
JinkProject commented 7 years ago

@Tripwire999 OK. Cool. Let me try that. Could this not be achieved the same why by just making ACEDrawingPenTool adhere to NSCoding protocol? Why did you use a separate object (DrawPathObject)

TripwireNL commented 7 years ago

@JinkProject It's because i'm using Realm and i'm not only storing the DrawPath stuff but also some other parts in Realm like lineAlpha, lineWidth, tooltype e.t.c.

JinkProject commented 7 years ago

@Tripwire999 How did you encode/decode the path?

JinkProject commented 7 years ago

@Tripwire999 Also, have you made the path variable from the ACEDrawingPenTool object a publicly, readwriteable property? I've done all of these things and I'm still not seeing the drawings on load.

JinkProject commented 7 years ago

@Tripwire999 NVM. Got it working. Looks great. Thanks for the help!

JinkProject commented 7 years ago

@acerbetti @Tripwire999 Would you guys be up for submitting a PR that supports storing drawings? We'd like to use this library as a pod in our projects, but we would obviously want to stay up to date on the latest changes.

acerbetti commented 7 years ago

Happy to accept and review any PR. But I don't have any bandwidth to maintain the lib right now

JinkProject commented 7 years ago

@acerbetti Roger that. I'll submit a PR.

TripwireNL commented 7 years ago

@JinkProject If you need help I'll be willing to lend a hand for saving and loading the drawings. Though I've modified the AceDrawingView code heavily the saving and loading shouldn't be that different than what i've got. Let me know!

JinkProject commented 7 years ago

@Tripwire999 Any help would be appreciated!