这是一个自我回答的问题,感谢我从 StackOverflow 和Ray Wenderlich 绘图教程中获得的各种帮助。我以为我会将各种片段放在一个包中。
我的问题是我想在大于 iphone 屏幕尺寸的 pdf 上进行手绘。因此,我选择 UIScrollView 来处理额外的大小,但正如其他帖子所指出的那样,您会遇到以下问题:
- 区分平移/捏合和绘图
- 处理缩放视图上的坐标校正
在这个问题中,Objective C: Drawing with Fingers on UIScrollView apouche给了我一个很好的指导来解决第一个问题。他建议使用自定义 UIPanGesturerecognizers 来区分绘图和滚动。我发现单指与双指滚动的混淆仍然有点笨拙,所以我使用铅笔的选择或导航栏中的 UISegmentedControl 在平移和绘制之间进行选择,以及是否可以通过设置捏合一个 BOOL drawActive。
这是 viewDidLoad 代码:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tempDrawImage.userInteractionEnabled =YES;
cumTranslation = CGPointMake(0,0);
[panDrawSelect setSelectedSegmentIndex:0];
drawActive = NO;
red = 0.0/255.0;
green = 0.0/255.0;
blue = 0.0/255.0;
brush = 3.0;
opacity = 1.0;
NSURL *pdfUrl = [NSURL fileURLWithPath:loadPath];
document = CGPDFDocumentCreateWithURL((__bridge CFURLRef)pdfUrl);
currentPage = 1;
CGPDFPageRef page = CGPDFDocumentGetPage(document, currentPage);
pageRect = CGPDFPageGetBoxRect(page, kCGPDFTrimBox);
NSLog(@"page width = %f", pageRect.size.width);
NSLog(@"page height = %f", pageRect.size.height);
pdfScale = self.view.frame.size.width/pageRect.size.width;
pageRect.origin = CGPointMake(0,0);
NSLog(@"page width = %f", pageRect.size.width);
NSLog(@"page height = %f", pageRect.size.height);
UIGraphicsBeginImageContext(pageRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
// White BG
CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0);
CGContextFillRect(context,pageRect);
CGContextSaveGState(context);
CGContextTranslateCTM(context, pageRect.size.width*0.75, pageRect.size.width+44);
CGContextScaleCTM(context, 1, -1);
CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(page, kCGPDFTrimBox, pageRect, 0, true));
CGContextRotateCTM(context, -1.5707);
CGContextDrawPDFPage(context, page);
CGContextRestoreGState(context);
UIImage *image =UIGraphicsGetImageFromCurrentImageContext();
initImage = image;
tempDrawImage =[[UIImageView alloc] initWithImage:image];
//CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
scrollView = [[UIScrollView alloc] initWithFrame:pageRect];
scrollView.delegate = self;
scrollView.minimumZoomScale = 0.3;
scrollView.maximumZoomScale = 3.0;
scrollView.contentSize= pageRect.size;
NSLog(@"page width = %f", pageRect.size.width);
NSLog(@"page height = %f", pageRect.size.height);
[scrollView addSubview:tempDrawImage];
[self.view addSubview:scrollView];
[self.view sendSubviewToBack: scrollView];
UIPanGestureRecognizer *Scrolling = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onScroll:)];
UIPinchGestureRecognizer *Zooming = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(onZoom:)];
[scrollView addGestureRecognizer:Scrolling];
[scrollView addGestureRecognizer:Zooming];
// Do any additional setup after loading the view.
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return tempDrawImage;
}
然后我在方法中使用了以下代码onScroll
:
- (void)onScroll:(UIPanGestureRecognizer*)sender
{
if (!drawActive) {
CGPoint translation = [sender translationInView:self.view];
sender.view.center = CGPointMake(sender.view.center.x + translation.x,
sender.view.center.y + translation.y);
[sender setTranslation:CGPointMake(0, 0) inView:self.view];
cumTranslation = CGPointMake(cumTranslation.x + translation.x,
cumTranslation.y + translation.y);
}
else {// Processing the drawing by using comparing:
if (sender.state == UIGestureRecognizerStateBegan)
{ /* drawing began */
mouseSwiped = NO;
lastPoint = [sender locationInView:self.tempDrawImage];
scaleLastPoint.x = lastPoint.x*scrollView.zoomScale;
scaleLastPoint.y = lastPoint.y*scrollView.zoomScale;
}
else if (sender.state == UIGestureRecognizerStateChanged)
{ /* drawing occured */
mouseSwiped = YES;
CGPoint currentPoint = [sender locationInView:self.tempDrawImage];
CGPoint scalePoint;
scalePoint.x = currentPoint.x*scrollView.zoomScale;
scalePoint.y = currentPoint.y*scrollView.zoomScale;
UIGraphicsBeginImageContext(self.tempDrawImage.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.tempDrawImage.frame.size.width, self.tempDrawImage.frame.size.height)];
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), scaleLastPoint.x, scaleLastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), scalePoint.x, scalePoint.y);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush );
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(),kCGBlendModeNormal);
CGContextStrokePath(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
[self.tempDrawImage setAlpha:opacity];
UIGraphicsEndImageContext();
scaleLastPoint = scalePoint;
}
else if (sender.state == UIGestureRecognizerStateEnded)
{ /* drawing ended */
if(!mouseSwiped) {
UIGraphicsBeginImageContext(self.tempDrawImage.frame.size);
[self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.tempDrawImage.frame.size.width, self.tempDrawImage.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, opacity);
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), scaleLastPoint.x, scaleLastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), scaleLastPoint.x, scaleLastPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
CGContextFlush(UIGraphicsGetCurrentContext());
self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}}
为了补偿缩放,以确保绘图注释没有偏移,我使用了上面包含的缩放,但在这里突出显示:
lastPoint = [sender locationInView:self.tempDrawImage];
scaleLastPoint.x = lastPoint.x*scrollView.zoomScale;
scaleLastPoint.y = lastPoint.y*scrollView.zoomScale;