带水平缩放的UIScrollView - 子视图中绘制的Bezier路径模糊

时间:2016-06-09 06:33:08

标签: ios swift uiscrollview uibezierpath cgaffinetransform

我有一个滚动视图,只能在缩放时水平缩放(基于this answer

内容视图有几个水平均匀分布的子项,并放置在不同的高度。基本上,我用点绘制图形。

每个标记都是一个自定义UIView子类,其标签为子视图,并在drawRect(_:)内绘制一个红色圆圈。

(内容视图使用Autolayout的滚动视图及其唯一子视图,但内容视图的所有子视图都放置了在运行时计算的帧;除了标记的标记定位之外没有约束)

我已经修改了上面链接的答案,因此 - 当缩放时 - 点水平间隔更大,但保持相同的大小

这是我的内容视图代码的一部分:

override var transform: CGAffineTransform {

    get {
        return super.transform
    }

    set {
        if let unzoomedViewHeight = unzoomedViewHeight {
            // ^Initial height of the content view, captured
            // on layoutSubviews() and used to calculate a
            // a zoom transform that preserves the height  
            // (see linked answer for details)

            // 1. Ignore vertical zooming for this view:

            var modified = newValue
            modified.d = 1.0
            modified.ty = (1.0 - modified.a) * unzoomedViewHeight/2
            super.transform = modified


            // 2. Ignore zooming altogether in marker subviews:

            var markerTransform = CGAffineTransformInvert(newValue)
            markerTransform.d = 1.0 // No y-scale

            for subview in subviews where subview is MarkerView {
                subview.transform = markerTransform
            }
        }
    }
}

接下来,我想用直线段连接我的点。问题是,当我缩放滚动视图时,片段变得模糊。

另外 模糊,因为我只是水平缩放,所以细分"剪切"一点(取决于它们的斜率),因此线宽变得不均匀:

enter image description here

(现在我在每对点之间放置一个中间视图,绘制一个段 - 但结果与单个路径相同)

我已经尝试使段绘图视图知道由父项应用于它们的变换,将其还原,然后相应地修改它们的帧(并重新绘制新边界内的路径);但它似乎无法发挥作用。

在滚动视图中绘制防缩码bezier路径的最佳方法是什么?

更新

我通过跟this answer跟一个类似的问题(几乎重复?)摆脱了像素化;在我的情况下,代码转换为:

func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat)
{
    for segment in contentView.subviews where segment is SegmentView {

        segment.layer.contentsScale = scale
        segment.setNeedsDisplay()
    }
}

...但是,由于仅在水平方向上拉伸(对角线)线段,我仍然存在不均匀的线宽问题。

1 个答案:

答案 0 :(得分:1)

我最初的想法是,在完全没有这样做之前,将图形存储为bezier路径而不是一组视图线和点视图,并且基于单个单元轴。您可以将数据转换为此表单,仅用于绘图。

因此,贝塞尔曲线路径上的所有点都归一化为0到1的范围。

完成后,您可以将变换应用于贝塞尔曲线路径以平移(移动)和缩放(缩放)到您想要的部分,然后以全分辨率绘制贝塞尔曲线路径。

这将有效并且与您当前的情况不同,因为您当前的代码会绘制视图然后进行缩放,以便您获得工件。上面的选项缩放路径然后绘制它。