开发者

Printing subview image to PDF in iOS

I am attempting to take a fingerpainted signature from the iPad's touch screen, print it to PDF, and then email the resulting PDF to a preset address. I have a UIView subclass written that adds lines between the current drag event's location to the last drag event's location, as shown below. I have had no troubles implementing the emailing portion. The subclass's declaration:

#import <UIKit/UIKit.h>

@interface SignatureView : UIView {
    UIImageView *drawImage;
    @public
    UIImage *cachedSignature;
}
@property (nonatomic, retain) UIImage* cachedSignature;
-(void) clearView;

@end

And implementation:

#import "SignatureView.h"

@implementation SignatureView

Boolean drawSignature=FALSE;
float oldTouchX=-1;
float oldTouchY=-1;
float nowTouchX=-1;
float nowTouchY=-1;
@synthesize cachedSignature;
//UIImage *cachedSignature=nil;

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code.
    }
    return self;
    if (cachedSignature==nil){
        if(UIGraphicsBeginImageContextWithOptions!=NULL){
            UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
        }els开发者_如何学Goe{
            UIGraphicsBeginImageContext(self.frame.size);
        }
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
        cachedSignature = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
}

- (void)drawRect:(CGRect)rect {
    //get image of current state of signature field
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    cachedSignature = UIGraphicsGetImageFromCurrentImageContext();

    //draw cached signature onto signature field, no matter what.

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextDrawImage(context, CGRectMake(0,0,302,90),cachedSignature.CGImage);

    if(oldTouchX>0 && oldTouchY>0 && nowTouchX>0 && nowTouchY>0){
        CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
        CGContextSetLineWidth(context, 2);
                //make change to signature field
        CGContextMoveToPoint(context, oldTouchX, oldTouchY);

        CGContextAddLineToPoint(context, nowTouchX, nowTouchY);
        CGContextStrokePath(context);
    }
 }
-(void) clearView{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetGrayFillColor(context, 0.75, 1.0);
    CGContextFillRect(context, CGRectMake(0,0,800,600));
    CGContextFlush(context);
    cachedSignature = UIGraphicsGetImageFromCurrentImageContext();
    [self setNeedsDisplay];
}

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint location=[[touches anyObject] locationInView:self];
    oldTouchX=nowTouchX;
    oldTouchY=nowTouchY;
    nowTouchX=location.x;
    nowTouchY=location.y;
    [self setNeedsDisplay];
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    CGPoint location=[[touches anyObject] locationInView:self];
    oldTouchX=nowTouchX;
    oldTouchY=nowTouchY;
    nowTouchX=location.x;
    nowTouchY=location.y;
    [self setNeedsDisplay];
}

 -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
     oldTouchX=-1;
     oldTouchY=-1;
     nowTouchX=-1;
     nowTouchY=-1;
 }

- (void)dealloc {
    [super dealloc];
}


@end

I am, however, having trouble printing the signature to a PDF. As I understand the above code, it should keep a copy of the signature before the last move was made as a UIImage named cachedSignature, accessible to all. However, when I try to write it to a PDF context with the following:

    UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);
    UIImage* background=[[UIImage alloc] initWithContentsOfFile:backgroundPath];
    // Create the PDF context using the default page size of 612 x 792.
    // Mark the beginning of a new page.
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0.0, 792);
    CGContextScaleCTM(context, 1.0, -1.0);
    //CGContextDrawImage(context, CGRectMake(0,0,612,790),background.CGImage);
    //draw signature images
    UIImage *y=clientSignatureView.cachedSignature;
    CGContextDrawImage(context, CGRectMake(450, 653, 600, 75), y.CGImage);
    //CGContextDrawImage(context, CGRectMake(75, 75, 300, 300),     techSignatureView.cachedSignature.CGImage);
    CGContextTranslateCTM(context, 0.0, 792);
    CGContextScaleCTM(context, 1.0, -1.0);

It fails. In this instance 'techSignatureView' and 'clientSignatureView' are instances of the custom UIView as defined above, connected to outlets in the same parent UIView as is running this code.

I don't know what's going wrong. I've taken out the call to print the background image, in case they were being printed 'behind' it, with no results. Using the debugger to inspect 'y' in the above code reveals that it has nil protocol entries and nil method entries; so I suspect it's not being accessed properly - beyond that, I'm clueless and don't know how to proceed.


First of all, your cachedSignature probably doesn't exist anymore when you try to draw it, because it's autoreleased. Use the property setter when you assign it, so instead of cachedSignature = foo write self.cachedSignature = foo.

Also, UIGraphicsGetImageFromCurrentImageContext only works for image contexts, you cannot use this in drawRect: with the current context. The drawRect: method takes care of drawing your view to the screen, you cannot create an image from the same context, you have to use UIGraphicsBeginImageContext to create a new context that you draw the image into. The drawRect: method is not the best place for that anyway, because performance will likely be bad if you render the image every time a touch moves. Instead, I'd suggest to render the signature to the image in your touchesEnded:withEvent: implementation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜