简体   繁体   English

如何旋转 CATextLayer 并保持其大小?

[英]How to rotate CATextLayer and preserve it's size?

I have a custom view, which I use for markup (draw lines and other figures on it).我有一个自定义视图,用于标记(在其上绘制线条和其他图形)。 The view controller recognizes touches and gestures and passes info to the view so it can draw itself properly.视图控制器识别触摸和手势并将信息传递给视图,以便它可以正确地绘制自己。 Each figure has a label ( CATextLayer ) with some figure info on it (line length for example).每个图形都有一个标签( CATextLayer ),上面有一些图形信息(例如线长)。

I added a rotation gesture recognizer to the view controller to rotate this drawing view.我在视图控制器中添加了一个旋转手势识别器来旋转这个绘图视图。 I want to rotate the view, but prevent labels from rotation (so they stay 0.0 degrees relative to the superview).我想旋转视图,但防止标签旋转(因此它们相对于超级视图保持 0.0 度)。 For this I calculate the new drawing view's angle relative to the superview and set label's angle property to the negative value, so I can rotate them oppositely.为此,我计算了新绘图视图相对于超级视图的角度,并将标签的角度属性设置为负值,以便我可以反向旋转它们。 For example, the view is rotated 30 degrees, then I rotate labels -30 degrees.例如,视图旋转 30 度,然后我将标签旋转 -30 度。

In the view drawing method which is responsible for drawing figures and setting the labels, I create new transform for each label each time the view needs to be redrawn:在负责绘制图形和设置标签的视图绘制方法中,每次需要重新绘制视图时,我都会为每个标签创建新的变换:

CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformRotate(transform, self.angle); //self.angle - rotation angle in radians
transform = CGAffineTransformScale(transform, scale, scale); //scale label (need this for pinch gesture, works as expected)
label.transform = transform;

All this stuff works if I rotate labels 90 degrees.如果我将标签旋转 90 度,所有这些东西都会起作用。 If the degree is not 0, 90, 180, etc, the label's frame changes: shrinks or enlarges, with large angles it even disappears.如果度数不是 0、90、180 等,标签的框架会发生变化:缩小或放大,大角度甚至消失。 I understand, that when you rotate the rectangle, it's frame should get bigger as it's pointed here: Why after rotating UIImageView size is getting changed?我明白,当你旋转矩形时,它的框架应该变大,因为它指向这里: 为什么旋转 UIImageView 大小会改变?

Is there a way to prevent CATextLayer from changing its shape when rotating?有没有办法防止CATextLayer在旋转时改变其形状?

Normal position of label:标签的正常位置: 正常位置

When rotated 90 degrees (everything is nice)旋转 90 度时(一切都很好) 90度

Rotated to some arbitrary angle (label frame is misshapen)旋转到任意角度(标签框变形) 放大的标签

The frame isn't that what you expected after a non-rectangular rotation.框架不是您在非矩形旋转后所期望的。

I see three possible solutions for your problem:对于您的问题,我看到了三种可能的解决方案:

  1. Calculate the correct size of your text, and set the frame by assigning appropriate values to position and bounds .计算文本的正确大小,并通过为positionbounds分配适当的值来设置框架。
  2. Create a plain CALayer for the background of each text layer, if the first solution doesn't help.如果第一个解决方案没有帮助,请为每个文本图层的背景创建一个普通的CALayer
  3. But it should be much easier if you're rotate the image only and keep the rotation of the text layers unchanged.但是,如果您只旋转图像并保持文本图层的旋转不变,这应该会容易得多。 You can achieve this by adding the text layers to the super layer of the image layer.您可以通过将文本图层添加到图像图层的超级图层来实现此目的。 With this setup you have just to calculate the new position of the text layers after rotation.使用此设置,您只需计算旋转后文本图层的新位置。

I'm very unsure whether the first two solutions are practicable, and I would prefer the third one.我不确定前两个解决方案是否可行,我更喜欢第三个。

The issue was occurring because I was resetting CATextLayer 's origin after setting its transform.出现问题是因为我在设置转换后重置CATextLayer的原点。 According to the transform property documentation:根据transform属性文档:

When the value of this property is anything other than the identity transform, the value in the frame property is undefined and should be ignored.当该属性的值不是恒等变换时,frame 属性中的值是未定义的,应该被忽略。

To change the position of a layer, use its position property.要更改图层的位置,请使用其position属性。

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

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