为什么图层变换会影响UIView的框架?

10

对UIView进行转换会影响其框架。对UIView层进行转换也以同样的方式影响视图框架。因此,缩放视图的层会缩放框架。我试图理解为什么对层进行变换会影响视图框架(即使设置了view.layer.masksToBounds = NO)。

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
NSLog(@"Before: %@", NSStringFromCGRect(view.frame));
// Output: {{0, 0}, {50, 50}}

// View transform applied
view.transform = CGAffineTransformMakeScale(2, 2);
NSLog(@"%@", NSStringFromCGRect(view.frame));
// Output: {{-25, -25}, {100, 100}}


// Layer transform applied
view.transform = CGAffineTransformIdentity;
view.layer.transform = CATransform3DMakeScale(2, 2, 1);
NSLog(@"%@", NSStringFromCGRect(view.frame));
// Output: {{-25, -25}, {100, 100}}

1
一旦您拥有一个变换,就不应该再查看帧值。来自UIView“frame”属性的文档:“警告:如果transform属性不是标识变换,则此属性的值未定义,因此应将其忽略。” - David Rönnqvist
谢谢@DavidRönnqvist。这正是我需要听到的解释类型。如果您将其作为答案,我会接受它。 - Warpling
3个回答

11

一旦使用了变换(transform)属性,就不应该再查看 frame 属性的值,因为此时它包含的内容是未定义的。这在 UIView 类中 frame 属性的文档中有提到:

警告

如果 transform 属性不是单位矩阵,那么此属性值是未定义的,因此应该忽略。

如果需要修改 frame,则必须使用 centerbounds 属性。


这份文档涉及到 view.transform 属性。它没有说明 view.layer.transform 是否会影响框架。但是通过实验,显然会产生影响。 - Glenn Schmidt
@Glenn Schmidt,一个 UIViewtransformframe 属性都是指向和来自其底层的 CALayer,因此所有内容都应该同样适用。 - bompf

2
一个 frame 是一个非常具体的东西。
这个矩形定义了视图在其父视图坐标系中的大小和位置。在布局操作期间,您使用此矩形来调整视图的大小和位置。
应用于视图的变换会影响该视图在父视图中的原点和大小,这就是为什么视图的框架会改变的原因。
转换子视图将影响子视图的框架,但不会影响它们的父视图的框架。
值得注意的是,bounds 在这方面与 frame 不同。视图的边界是视图在其自己的坐标系统中的原点和大小。变换不应该改变视图的边界,因为变换改变了视图在外部坐标系中的大小和位置,但不改变视图的内部坐标系。

谢谢Jeffery,我知道将变换应用于视图会影响其框架,但我想了解的是为什么将变换应用于视图层会影响其框架。 - Warpling
从UIView的frame属性文档中可以看到:“警告:如果transform属性不是标识变换,那么此属性的值是未定义的,因此应该忽略它。” - David Rönnqvist

1

框架是一种计算属性。基本上,它是从中心点和边界合成的。(要了解更多,请搜索CALayer的anchorPoint)。此外,当考虑到变换时,框架将成为一个边界框,该框将覆盖原始框,即使应用旋转或缩放。而hitTest和pointInside的默认实现将使用最终框架,这意味着您可以正常触摸已翻译或旋转的视图。


奇怪的是,框架通常是明确设置的,但也是一个计算属性。不过,在hitTestpointInside的上下文中这是有意义的! - Warpling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接