简体   繁体   English

如何在转换后的UIView上重新绘制缩放的文本?

[英]How can I redraw zoomed text on a transformed UIView?

I'm currently implementing an expanding timeline. 我目前正在执行一个扩展的时间表。 When I pinch zoom into the timeline, I need my drawn text to stay at the same relative locations on the UIView they're drawn on inside the UIScrollView that handles the zooming. 当我将缩放捏到时间轴上时,我需要绘制的文本保持在UIView上相同的相对位置上,这些相对位置是在处理缩放的UIScrollView内绘制的。 (Essentially like pins on GoogleMaps) However, I don't want to zoom vertically, so I apply a transform by overriding: (本质上就像GoogleMaps上的图钉一样)但是,我不想垂直缩放,因此我通过覆盖应用了一个变换:

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

This works great in keeping the timeline fixed vertically and allowing it to expand horizontally. 这对于保持时间轴垂直固定并使其水平扩展非常有用。 However, I am drawing my text labels as such in a method called during setNeedsDisplay: 但是,我正在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]];
}

This draws my text at the correct position in the scrollview, and nearly works perfectly. 这会将我的文本绘制在滚动视图中的正确位置,并且几乎可以正常工作。 However, because of my transform to keep the zooming view static vertically, the text expands horizontally and not vertically, and so stretches out horribly. 但是,由于我进行了变换以保持缩放视图在垂直方向上保持静态,因此文本在水平方向上而不是在垂直方向上扩展,因此扩展得很厉害。 I can't seem to get the text to redraw at the correct aspect ratio. 我似乎无法以正确的宽高比重绘文本。 Using UILabels works, however I am going to be rendering and manipulating upwards of 1,000 such labels, so I'd preferably like to draw static images in drawRect or something similar. 使用UILabels可以工作,但是我将渲染和操纵多达1,000个这样的标签,所以我最好在drawRect或类似的东西上绘制静态图像。

I've tried changing the CGRect I'm drawing the text in (was worth a shot), and applying CGAffineTransformIdentity isn't possible because I'm already transforming the view to keep it from zooming vertically. 我尝试更改要在其中绘制文本的CGRect(值得一试),并且无法应用CGAffineTransformIdentity,因为我已经在转换视图以防止其垂直缩放。 I've also tried drawing the text in various Views to no avail, and again, I'd rather not populate an obscene amount of objects if I can avoid it. 我也尝试过在各种视图中绘制文本都无济于事,如果可以避免的话,我宁愿不要填充大量的淫秽对象。

Thanks for any help! 谢谢你的帮助!

Instead of applying a transform inside the 'setTransform:' method, I intercepts the scale at which it is being transformed, and resize the frame of the view being transformed. 我没有在'setTransform:'方法中应用转换,而是截取了要转换的比例,并调整了要转换的视图框架的大小。 The code (roughly) follows: 代码(大致)如下:

- (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);
}

As mentioned in the comments, the transform value of the CGAffineTransform is reset each time a new zooming action occurs (however, it is kept for the duration of the zooming action). 作为评价所述,变换CGAffineTransform的值重置每一个新的缩放动作发生时间(然而,它保持在对于变焦动作的持续时间)。 So, I keep two instance variables in my UIView subclass (not sure if it's incredibly elegant, but it's not insanely terrible): the original frame the the view was instantiated with, and the "current" zoom scale of the view (prior to the current zooming action). 因此,我在UIView子类中保留了两个实例变量(不知道它是否非常优雅,但并不是很糟糕):实例化视图的原始框架,以及视图的“当前”缩放比例(当前的缩放动作)。

The _originalFrame is what is referenced in order to determine the proper sizing of the now zoomed frame, and the _zoomScale (the scale of the view prior to the current zooming action) is set to the value of _newZoomScale when the didFinishZooming callback is called in the UIScrollView containing this UIView. _originalFrame是为了确定当前缩放的帧的适当大小而引用的内容,并且当在_newZoomScale中调用didFinishZooming回调时, _zoomScale (当前缩放操作之前的视图比例)的值设置为_newZoomScale的值。包含此UIView的UIScrollView。

All of this allows for the coordinate system of the UIView to not be transformed during zooming, so text, etc. may be drawn on the view without any distortion. 所有这些使得UIView的坐标系在缩放期间不会发生变换,因此可以在视图上绘制文本等而不会产生任何变形。 Looking back at this solution, I'd wager a guess that you could also account for the transform and draw based on a stretched coordinate system. 回顾这个解决方案,我猜您也可以考虑基于拉伸坐标系的变换和绘制。 Not sure which is more effective. 不确定哪个更有效。 I had a slight concern by not calling super in setTransform: , but I haven't noticed any ill effects after about 6 months of use and development. 我对setTransform:没有调用super感到有点担心,但是经过大约6个月的使用和开发,我没有发现任何不良影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM