【问题标题】:How to Prevent or Compensate For Scaling Transforms of Core Graphic Paths?如何防止或补偿核心图形路径的缩放变换?
【发布时间】:2009-10-15 19:26:53
【问题描述】:

我正在尝试围绕 UIView 创建一个 "marching ants" (an animated dashed line) selection indicator,其中包含一个 UIImageView 子视图。使用核心图形在 UIView 周围绘制虚线很简单:

-(void) drawSelectedMarquee{
     CGContextRef c=UIGraphicsGetCurrentContext();
 CGContextSetStrokeColorWithColor(c, [[UIColor whiteColor] CGColor] );
 CGRect f=self.bounds;
 CGContextSetLineWidth(c, 2.0);
 CGFloat dashes[]={1,2};
 CGContextSetLineDash(c, 0, dashes, 2);
 CGContextBeginPath(c);
 CGContextAddRect(c, f);
 CGContextStrokePath(c);
}

但是,我需要使用仿射变换来缩放(和旋转)视图,以便可以缩放和旋转内部的 UIImageView:

-(void) scaleByX:(CGFloat) xScale andY:(CGFloat) yScale{
 [UIView beginAnimations:nil context:nil];
 [UIView setAnimationDuration:0.1];
 [UIView setAnimationBeginsFromCurrentState:YES];
 self.transform=CGAffineTransformScale(self.transform, xScale, yScale);
 [UIView commitAnimations];
}

但是,由于核心图形绘制了相对“用户空间点”,这些点显然也被变换缩放,缩放视图会导致虚线按比例缩放。因此,随着视图比例变小,线变细,虚线更靠近,视图缩放更大,线变粗,虚线分开。

作为界面元素,选择框应保持固定宽度和固定大小的破折号。我试过旋转和缩放主视图的 UIImageView 子视图,但这会导致 UIImageView 超出超级视图。

我可以想出一些蛮力方法来正确绘制选取框。我可以跟踪视图的绝对大小,然后在每次重绘时重新计算最终用户空间单位,或者在每次 UIImageView 时创建一个带有选择框的新视图。但这些解决方案不优雅且容易出错。

我想我在文档中遗漏了有关如何在 UIView 中绘制和转换图形的内容。

[更新:我已经决定在 iPhone 的小屏幕上使用行军蚂蚁没有用,所以我采用了另一种方法。但是我仍然对这个特定问题的解决方案感兴趣。]

【问题讨论】:

    标签: iphone cocoa cocoa-touch iphone-sdk-3.0


    【解决方案1】:

    我认为您没有遗漏文档中的任何内容,而是您可能遗漏了缩放提供的概念。如果您缩放视图或图层的内容,它将调整内容中所有内容的大小。这实际上是可取的。它使缩放变得容易,而无需自己管理所有子视图缩放。听起来你需要的是在你的视图前面添加一个覆盖层。

    我不确定您是如何调整视图大小的,但是当您的视图加载时,添加一个覆盖核心动画层,您可以在视图缩放时调整它的大小。请注意,在提及覆盖层时,我使用了调整大小而不是缩放。

    要使其正常工作,您必须确保覆盖层是您正在缩放的​​视图的兄弟而不是子视图,否则它也会被缩放。

    有趣的是,您可以使用 CAShapeLayer 并利用其 lineDashPattern 属性,该属性采用浮点数组来指定可以勾勒出您指定的 CGRect 的虚线图案。然后可以使用 lineDashPhase 属性和 CABasicAnimation 为该模式设置动画,使其具有行进的蚂蚁效果。如果您感兴趣,我可以详细说明。

    更新:我继续前进,wrote a blog post on getting the marching ants effect working using Core Animation。抱歉,我没有时间尝试解决您的问题,但这篇博文可能会帮助您指出正确的方向。

    【讨论】:

    • 我将研究核心动画解决方案。我在使用重叠视图或图层时遇到的问题是,当图像缩放时,包含图像视图的视图框架必须增长和缩小。对于用作覆盖的任何独立视图也是如此。将帧与图像的比例同步会产生明显的伪影。希望 CA 层不会有这个问题。
    • 我将继续接受这个作为答案,因为我认为不可能完全按照我的意愿去做。这个答案在同一问题空间中提供了大量非常有用的信息。
    【解决方案2】:

    您可能想要检查正在执行核心图形绘制的任何视图的 contentMode。我最近遇到了一个问题,我在可变高度的 tableview 单元格中有垂直虚线,其比例与您描述的方式相似。如果将 contentMode 设置为 UIViewContentModeRedraw,它应该在帧更改时使用 drawRect 手动绘制视图,而不是缩放它。

    【讨论】:

      【解决方案3】:

      我认为你可以反转变换来做你想做的事。如果我错了,如果你知道你的比例和平移值,你应该能够构建相反的变换。

      另一种方法是在图层上绘制,而不是直接在视图中绘制并且只缩放图层。

      在许多应用程序(如 adobe illustrator)中,选框矩形实际上是主窗口前面的一个透明窗口。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-11
        • 2014-02-20
        • 2011-06-25
        • 1970-01-01
        • 2023-02-18
        • 1970-01-01
        • 2014-03-17
        • 1970-01-01
        相关资源
        最近更新 更多