我正试图从iPad的触摸屏上取下手指画签,将其打印为PDF,然后将生成的PDF通过电子邮件发送到预设地址。我编写了一个UIView子类,它在当前拖动事件的位置和最后一个拖动事件的位置之间添加了行,如下所示。我没有遇到麻烦实施电子邮件部分。子类的声明:
#import <UIKit/UIKit.h>
@interface SignatureView : UIView {
UIImageView *drawImage;
@public
UIImage *cachedSignature;
}
@property (nonatomic, retain) UIImage* cachedSignature;
-(void) clearView;
@end
并实施:
#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);
}else{
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
但是,我无法将签名打印到PDF。据我了解上面的代码,它应该在最后一次移动之前保留一份签名副本,作为名为cachedSignature的UIImage,所有人都可以访问。但是,当我尝试使用以下内容将其写入PDF上下文时:
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);
失败了。在这个例子中,'techSignatureView'和'clientSignatureView'是上面定义的自定义UIView的实例,连接到与运行此代码相同的父UIView中的出口。
我不知道出了什么问题。我已经取出了打印背景图片的电话,以防它们被打印在“后面”,没有结果。使用调试器检查上面代码中的“y”表明它有nil协议条目和nil方法条目;所以我怀疑它没有被正确访问 - 除此之外,我无能为力,不知道如何继续。
答案 0 :(得分:0)
首先,当你尝试绘制它时,你的cachedSignature可能不再存在,因为它是自动释放的。分配时使用属性设置器,而不是cachedSignature = foo
写self.cachedSignature = foo
。
此外,UIGraphicsGetImageFromCurrentImageContext
仅适用于图像上下文,您不能在drawRect:
中使用当前上下文。 drawRect:
方法负责将视图绘制到屏幕上,无法从同一上下文创建图像,必须使用UIGraphicsBeginImageContext
创建绘制图像的新上下文。无论如何,drawRect:
方法并不是最好的方法,因为如果每次触摸移动时渲染图像,性能可能会很差。相反,我建议在touchesEnded:withEvent:
实现中将签名呈现给图像。