0

我目前正在实施一个扩展的时间表。当我捏放大到时间线时,我需要绘制的文本保持在 UIView 上的相同相对位置,它们在处理缩放的 UIScrollView 内绘制。(基本上就像谷歌地图上的图钉)但是,我不想垂直缩放,所以我通过覆盖来应用变换:

- (void)setTransform:(CGAffineTransform)newValue;
{
    newValue.d = 1.0;
    [super setTransform:newValue];
}

这在保持时间线垂直固定并允许它水平扩展方面非常有效。但是,我在 setNeedsDisplay 期间调用的方法中绘制我的文本标签:

for (int i = 1; i < 11; i++)
{
    CGRect newFrame = CGRectMake(i * (512.0/11.0) - (512.0/11.0/2.0), self.frame.size.height - 16.0, 512.0/11.0, 32.0);
    NSString *label = [NSString stringWithFormat:@"%d", i+1];
    [label drawInRect:newFrame withFont:[UIFont systemFontOfSize:14.0]];
}

这会将我的文本绘制在滚动视图中的正确位置,并且几乎可以完美运行。但是,由于我的变换使缩放视图垂直保持静态,文本水平扩展而不是垂直扩展,因此伸展得非常可怕。我似乎无法让文本以正确的纵横比重绘。使用 UILabels 是可行的,但是我将渲染和操作超过 1,000 个这样的标签,所以我最好在 drawRect 或类似的东西中绘制静态图像。

我已经尝试更改要在其中绘制文本的 CGRect(值得一试),并且无法应用 CGAffineTransformIdentity,因为我已经在转换视图以防止其垂直缩放。我还尝试在各种视图中绘制文本但无济于事,而且,如果可以避免的话,我宁愿不填充大量的对象。

谢谢你的帮助!

4

1 回答 1

1

我没有在 'setTransform:' 方法中应用变换,而是截取它正在变换的比例,并调整正在变换的视图框架的大小。代码(大致)如下:

- (void)setTransform:(CGAffineTransform)newValue;
{   
    // The 'a' value of the transform is the transform's new scale of the view, which is reset after the zooming action completes
    //  newZoomScale should therefore be kept while zooming, and then zoomScale should be updated upon completion
    _newZoomScale = _zoomScale * newValue.a;

    if (_newZoomScale < 1.0)
        _newZoomScale = 1.0;

    // Resize self
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, _originalFrame.size.width * _newZoomScale, self.frame.size.height);
}

如评论中所述,每次发生新的缩放动作时都会重置 CGAffineTransform 的变换值(但是,在缩放动作期间保留它)。所以,我在我的 UIView 子类中保留了两个实例变量(不确定它是否非常优雅,但它并不是非常糟糕):视图实例化的原始帧,以及视图的“当前”缩放比例(在当前缩放动作)。

_originalFrame是为了确定当前缩放帧的正确大小而引用的内容,并且_zoomScale(当前缩放操作之前的视图比例)设置为在包含此 UIView 的 UIScrollView 中调用回调_newZoomScale时的值didFinishZooming.

所有这些都允许 UIView 的坐标系在缩放期间不会发生变化,因此可以在视图上绘制文本等而不会产生任何失真。回顾这个解决方案,我猜你也可以考虑基于拉伸坐标系的变换和绘制。不确定哪个更有效。我有点担心没有打电话给 super in setTransform:,但是在使用和开发大约 6 个月后,我没有注意到任何不良影响。

于 2012-03-01T20:43:59.117 回答