-2

我最近让我的应用程序与最新的 Retina iPad 兼容,但我的绘图变得模糊不清。然后我尝试更改 contextWithOptions,但是当我绘制时它变得非常滞后和锯齿状。我试过的一切都不起作用。有任何想法吗?

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    mouseSwiped = YES;

    UITouch *touch = [touches anyObject];
    CGPoint currentPoint = [touch locationInView:self.view];
    if (UIGraphicsBeginImageContextWithOptions != NULL) {
        UIGraphicsBeginImageContextWithOptions((self.view.frame.size), NO, 1);
        //becomes laggy if I set it to 0 or 2. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    } else {
        UIGraphicsBeginImageContext(self.view.frame.size);
    }
    [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.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();

    lastPoint = currentPoint;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if(!mouseSwiped) {
        UIGraphicsBeginImageContext(self.view.frame.size);
        [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
        CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush);
        CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, opacity);
        CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
        CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
        CGContextStrokePath(UIGraphicsGetCurrentContext());
        CGContextFlush(UIGraphicsGetCurrentContext());
        self.tempDrawImage.image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }

      UIGraphicsBeginImageContextWithOptions((self.view.frame.size), NO, 0);
    [self.mainImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:1.0];
    [self.tempDrawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) blendMode:kCGBlendModeNormal alpha:opacity];
    self.mainImage.image = UIGraphicsGetImageFromCurrentImageContext();
    self.tempDrawImage.image = nil;
    UIGraphicsEndImageContext();
}

也许我应该在用户结束触摸时更改图像?请问有什么帮助吗?

4

1 回答 1

1

正确,您不想尝试为视图中的每次触摸创建图像。你只是想画你的路。或者,更准确地说,您希望您的触摸手势 (a) 更新由一堆路径数组组成的模型(每条路径本身就是一个点数组);(b) 调用必要的调用来更新更新模型的 UI。

要渲染图纸,您有两种基本方法:

  1. 创建一个UIView子类,该子类具有drawRect遍历您的一系列路径并绘制它们的方法;或者

  2. 创建一个CAShapeLayer使用您的路径的,然后执行[self.view.layer addSublayer:layer].

任何一种技术都很好。但请注意,在这两种技术中,您都不会在手势期间执行任何UIGraphicsBeginImageContextUIGraphicsGetImageFromCurrentImageContext和。UIGraphicsEndImageContext只有当您想要将绘图保存为图像时(大概在用户的绘图手势完成之后),您才会这样做。

但是,如果您这样做,即使在 Retina 屏幕上,您也绝对可以跟上用户的手势。处理图像是一个缓慢且内存效率低下的过程,因此您只想谨慎行事。

顺便说一句,如果您将这一系列路径作为绘图模型的中心部分,它也会打开其他机会。例如,只需从模型中删除路径对象并重新渲染视图,就可以轻松“撤消”路径。但是,如果您将其保存为图像,则删除几个描边就变得不切实际了。

最后,您必须决定您的应用程序是矢量图形应用程序(您保存的文件是路径数组,可能还可以选择保存图像)还是更像位图编辑器(其中,最后,您丢弃矢量信息并仅保存位图)。无论您采用哪种方法,在手势过程中使用路径对象都可能使 UI 响应更快。

于 2013-10-18T05:11:18.190 回答