Search code examples
iosobjective-cuiimagecgcontextuitouch

Why the responds is slow as stroke PNG images with UItouch?


I used below code to stroke PNG with finger move. There has 2 UIImage View. One locates at background to put background image there. The other one is clear UIImage view to stroke PNG images on top of it.

  -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
   {
       for (UITouch * touch in touches) {

          currentPoint = [touch locationInView:self.view];
          lastPoint = [touch previousLocationInView:self.view];

    //set up array to make space between PNG images
          if (ABS(currentPoint.x-lastPoint.x)>16
               || ABS(currentPoint.y - lastPoint.y) > 13) {

              [brushLocations addObject:[NSValue valueWithCGPoint:currentPoint]];


      }
        [self drawingWithArray];

 }

  - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

         [brushLocations removeAllObjects];//reset


     }


 -(void)drawingWithArray{



     UIGraphicsBeginImageContext(self.view.frame.size);
     [drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width,    drawImage.frame.size.height)];

     for (int i=0; i<[brushLocations count]; i++) {

 CGPoint center =[[brushLocations objectAtIndex:i]CGPointValue];


    // bokehImage is UIImage 

         bokehImage=[bokehImgArray objectAtIndex: i%[bokehImgArray count]];

 /// the PNG images are not semi-transparent, even set the alpha is 0.5??

         [bokehImage drawAtPoint:center blendMode:kCGBlendModeOverlay alpha:0.5f];

//drawImage is uiimage view on top of background image view for stroke PNG images.
     drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();

}

Now, I got problem is the respond is slow. The PNG images didn’t display immediately while finger move on device (IPad4).

Also, the PNG images are not semi-transparent. I suppose that the function of “drawAtPoint .. blendMode .. alpha “ can make images to be semi-transparent (set 0.5 alpha).


Solution

  • Yes, something like this should work:

    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        for (UITouch * touch in touches) {
            currentPoint = [touch locationInView:self.view];
            lastPoint = [touch previousLocationInView:self.view];
            //set up array to make space between PNG images
            if (ABS(currentPoint.x-lastPoint.x)>16
                || ABS(currentPoint.y - lastPoint.y) > 13) {
                [brushLocations addObject:[NSValue valueWithCGPoint:currentPoint]];
            }
    //        [self drawingWithArray]; // don't call draw routine during touch handler
             [self setNeedsDisplay]; // queue the redraw instead
        }
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
    // Not needed here
    //    [brushLocations removeAllObjects];//reset
    }
    
    //-(void)drawingWithArray
    - (void)drawRect:(CGRect)rect
    {
        // CGContext is already set when drawRect is called
    //    UIGraphicsBeginImageContext(self.view.frame.size);
    //    [drawImage.image drawInRect:CGRectMake(0, 0, drawImage.frame.size.width, drawImage.frame.size.height)];
        [drawImage.image drawInRect:rect];
        for (int i=0; i<[brushLocations count]; i++) {
            CGPoint center =[[brushLocations objectAtIndex:i]CGPointValue];
            // bokehImage is UIImage
            bokehImage=[bokehImgArray objectAtIndex: i%[bokehImgArray count]];
            // the PNG images are not semi-transparent, even set the alpha is 0.5??
            [bokehImage drawAtPoint:center blendMode:kCGBlendModeOverlay alpha:0.5f];
            //drawImage is uiimage view on top of background image view for stroke PNG images.
            drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
    //        UIGraphicsEndImageContext();
        }
        [brushLocations removeAllObjects];//reset
    }