ios рисование на uiscrollview с панорамированием и щипком

Это вопрос, на который я отвечаю сам за себя, в благодарность за различную помощь, которую я получил как от StackOverflow, так и от учебник Рэя Вендерлиха по рисованию. Я решил собрать разные фрагменты в один пакет.

Моя проблема заключалась в том, что я хотел рисовать от руки в формате PDF, превышающем размер экрана iPhone. Поэтому я выбрал UIScrollView для обработки дополнительного размера, но, как указывалось в других сообщениях, вы сталкиваетесь со следующими проблемами:

  • различение между панорамированием/щипком и рисованием
  • обработка поправок к координатам в увеличенном виде

в этом вопросе Цель C: Рисование пальцами в UIScrollView apouche дал мне отличный совет по исправлению первой проблемы. Он предложил использовать пользовательские распознаватели жестов UIPanGesture, чтобы различать рисование и прокрутку. Я обнаружил, что путаница с прокруткой одним и двумя пальцами все еще немного неуклюжа, поэтому я использовал либо выбор карандашей, либо 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;  

comment
Можете ли вы привести рабочий пример по этому поводу?   -  person Mark    schedule 03.06.2014


Ответы (1)


Ответ в самом вопросе

вот результат:

панорамирование/масштабирование и рисование экрана

person Neil MCCABE    schedule 06.07.2013
comment
Кстати, я обнаружил, что генерировать UIScrollview и UIImageView программно было проще, чем помещать их в IB. - person Neil MCCABE; 06.07.2013
comment
После рисования изображение обрезается, пожалуйста, помогите мне в этом. - person Anjaneyulu Battula; 13.10.2015