使用图纸视图进行缩放

时间:2012-08-28 14:09:22

标签: objective-c ios uiview zoom drawrect

我正在寻找一种解决方案,以便在绘图视图上进行漂亮的缩放。 在我的应用程序中,我有一个视图与另一个UIView(用作绘图视图),当我在它上画一个笔划,笔画是完美的。但是当我缩放视图时,我有这种非常难看的效果(像素化笔划):screen shot http://data.imagup.com/10/1160827911.5509png

url image

是否有解决方案以获得适当的中风?

我的UIViewController有一个类似的层次结构:

  • 的UIViewController
    • 滚动型
      • 查看zoomable(使用viewForZoomingInScrollView方法定义)
        • 图片视图
        • 图纸视图

非常感谢!

此致 塞巴斯蒂安;)

3 个答案:

答案 0 :(得分:4)

我正在制作矢量绘图应用程序,让我告诉你,正确完成这项工作并不是一项微不足道的任务,需要相当多的工作。

要记住一些问题:

  • 如果您不使用矢量图形(例如,CGPaths) 矢量)你将无法删除像素化。一个UIImage, 例如,只有这么多分辨率。
  • 为了让您的绘图看起来不像素化,您将会这样做 必须重绘一切。如果你有很多绘图,这可以 执行这项艰巨的任务。
  • 具有良好的分辨率虽然缩放几乎是不可能的,因为它需要过大的上下文,并且您的绘图可能会超出设备的功能

我使用核心图形来绘制图形,所以我解决这个问题的方法是分配和管理多个CGContexts并将它们用作缓冲区。我有一个上下文始终保持在我最小的缩放级别(比例因子为1)。这个背景在任何时候都被吸引进去,并且当它完全被解除时,没有时间用于重绘,因为它已经完成了。另一个上下文用于绘制缩放时的绘图。未缩放时,将忽略该上下文(因为无论如何都必须根据新的缩放级别重新绘制)。我如何执行缩放的高级算法如下:

- (IBAction)handlePinchGesture:(UIGestureRecognizer *)sender
{
    if(sender.state == UIGestureRecognizerStateBegan)
    {
         //draw an image from the unzoomedContext into my current view

             //set the scale transformation of my current view to be equal to "currentZoom", a property of the view that keeps track of the actual zoom level
    }
    else if(sender.state == UIGestureRecognizerStateChanged)
    {
         //determine the new zoom level and transform the current view, keeping track in the currentZoom property

             //zooming will be pixelated.
    }
    else if(sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateCancelled)
    {
             if(currentZoom == 1.0)
             {
                   //you are done because the unzoomedContext image is already drawn into the view!
             }
             else
             {
                   //you are zoomed in and will have to do special drawing

                   //perform drawing into your zoomedContext
                   //scale the zoomedContext

                   //set the scale of your current view to be equal to 1.0

                   //draw the zoomedContext into the current view.  It will not be pixelated!

                   //any drawing done while zoomed needs to be "scaled" based on your current zoom and translation amounts and drawn into both contexts
             }

    }

}

这对我来说变得更加复杂,因为我有缓冲区的额外缓冲区,因为当有大量绘图时,绘制路径图像比绘制路径要快得多。

在管理多个上下文之间,调整代码以有效地绘制到多个上下文中,遵循适当的OOD,根据当前的缩放和平移缩放新绘图等,这是一项任务的重点。希望这可以激励你并让你走上正确的轨道,或者你决定摆脱那个像素化是不值得的努力:)

答案 1 :(得分:1)

我遇到了同样的问题并找到了解决方案:告诉视图使用CATiledLayer作为支持层,然后告诉视图它支持多少级别的缩放。这对我有用,我的绘图方法会在(父)视图缩放时自动调用。

levelsOfDetaillevelsOfDetailBias的简短说明:

  • levelsOfDetail确定总共有多少缩放级别
  • levelsOfDetailBias确定有多少人正在放大。

所以在我的例子中我有4个缩放级别,3个放大,1个是非缩放级别,这意味着我的视图只在放大时重绘。

@imprementation MyZoomableView

+ (Class)layerClass
{
    return [CATiledLayer class];
}


- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame])) {
        ((CATiledLayer *)self.layer).levelsOfDetail = 4;
        ((CATiledLayer *)self.layer).levelsOfDetailBias = 3;
    }
    return self;
}

@end

答案 2 :(得分:0)

[self setContentScaleFactor:scale];委托方法中使用scrollViewDidEndZooming: