ios绘图在uiscrollview与泛和捏

时间:2013-07-06 10:18:51

标签: uiscrollview drawing quartz-graphics uipangesturerecognizer uipinchgesturerecognizer

这是一个自我回答的问题,感谢我从StackOverflow和Ray Wenderlich tutorial on drawing获得的各种帮助。我以为我会把各种片段放在一个包中。

我的问题是我想在大于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;  

1 个答案:

答案 0 :(得分:1)

答案就在于问题本身

这是输出:

pan/zoom and draw screen