为什么 UIPickerTableViewWrapperCell 的“childView.convert(childView.bounds, to: parentView)”不等于“childView.frame”?
Why `childView.convert(childView.bounds, to: parentView)` is not equal to `childView.frame` for UIPickerTableViewWrapperCell?
按照我的理解,frame是使用父视图坐标系的view的位置和大小,bounds是使用自己坐标系的view的位置和大小,也就是说childView.convert(childView.bounds, to: parentView)
应该等于childView.frame
.
但是我发现UIPickerTableViewWrapperCell
不是这样的,从图中可以看出,frame是(origin = (x = 0, y = 160032.44775782057), size = (width = 134, height = 30.248210824676789))
,而convert(bounds, to: parentView)
是(origin = (x = -71.984082796011151, y = 160032.44585526528), size = (width = 134.04199076956854, height = 29.70736933068838))
为什么这两个值不同?
经过一些挖掘,我找到了 an instructive article 这可能有助于您理解为什么会出现这种看似不一致的情况。
为了避免以后出现问题link,我将在下面添加场景。
作者首先以在屏幕上绘制的矩形为例。他们使用以下函数打印出框架和边界值:
private func printAll() {
print("=========================")
print("X : ", self.orangeView.frame.origin.x)
print("Y : ", self.orangeView.frame.origin.y)
print("width : ", self.orangeView.frame.size.width)
print("height : ", self.orangeView.frame.size.height)
print("=========================")
print("X : ", self.orangeView.bounds.origin.x)
print("Y : ", self.orangeView.bounds.origin.y)
print("width : ", self.orangeView.bounds.size.width)
print("height : ", self.orangeView.bounds.size.height)
print("=========================")
}
使用这个,它们最初以相等的宽度和高度开始:
=========================
X : 87.0
Y : 384.0
width : 240.0
height : 128.0
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
然后他们对矩形执行变换以旋转它:
self.orangeView.transform = CGAffineTransform(rotationAngle: 5)
当然,这会导致元素的高度和宽度在父 (.frame
) 范围内发生变化:
=========================
X : 111.58938416597198
Y : 314.7747071707769
width : 190.82123166805604
height : 266.45058565844624
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
当然,这是因为通过旋转绘制的矩形,取景矩形的大小发生了变化,即使绘制的矩形没有改变尺寸。 Apple 也完全意识到这一点 as indicated in their documentation,声明如下:
Warning
If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
这很重要,因为我们可以从您提供的数据中推断出一些重要的行为。具体来说,如果我们忽略坐标,而是查看高度和宽度值,我们会看到以下差异:
frame: (width = 134, height = 30.248210824676789)
bounds: (width = 134, height = 32)
convert: (width = 134.04199076956854, height = 29.70736933068838)
查看图像中的 UI 元素本身,我们甚至看到垂直“挤压”的文本,表明这些元素很可能以某种方式应用了变换。这可能会导致 Apple 文档中指出的上述未定义行为。正如 Apple 在他们的文档中指出的那样,当转换 属性 不是身份转换时,应该忽略 属性 的值。
不幸的是,我们无法验证这就是问题的原因,因为 UIKit
,据我了解,不共享它的源代码,但转换导致未定义的行为似乎我们可以合理得出的最佳解释。
按照我的理解,frame是使用父视图坐标系的view的位置和大小,bounds是使用自己坐标系的view的位置和大小,也就是说childView.convert(childView.bounds, to: parentView)
应该等于childView.frame
.
但是我发现UIPickerTableViewWrapperCell
不是这样的,从图中可以看出,frame是(origin = (x = 0, y = 160032.44775782057), size = (width = 134, height = 30.248210824676789))
,而convert(bounds, to: parentView)
是(origin = (x = -71.984082796011151, y = 160032.44585526528), size = (width = 134.04199076956854, height = 29.70736933068838))
为什么这两个值不同?
经过一些挖掘,我找到了 an instructive article 这可能有助于您理解为什么会出现这种看似不一致的情况。
为了避免以后出现问题link,我将在下面添加场景。
作者首先以在屏幕上绘制的矩形为例。他们使用以下函数打印出框架和边界值:
private func printAll() {
print("=========================")
print("X : ", self.orangeView.frame.origin.x)
print("Y : ", self.orangeView.frame.origin.y)
print("width : ", self.orangeView.frame.size.width)
print("height : ", self.orangeView.frame.size.height)
print("=========================")
print("X : ", self.orangeView.bounds.origin.x)
print("Y : ", self.orangeView.bounds.origin.y)
print("width : ", self.orangeView.bounds.size.width)
print("height : ", self.orangeView.bounds.size.height)
print("=========================")
}
使用这个,它们最初以相等的宽度和高度开始:
=========================
X : 87.0
Y : 384.0
width : 240.0
height : 128.0
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
然后他们对矩形执行变换以旋转它:
self.orangeView.transform = CGAffineTransform(rotationAngle: 5)
当然,这会导致元素的高度和宽度在父 (.frame
) 范围内发生变化:
=========================
X : 111.58938416597198
Y : 314.7747071707769
width : 190.82123166805604
height : 266.45058565844624
=========================
X : 0.0
Y : 0.0
width : 240.0
height : 128.0
=========================
当然,这是因为通过旋转绘制的矩形,取景矩形的大小发生了变化,即使绘制的矩形没有改变尺寸。 Apple 也完全意识到这一点 as indicated in their documentation,声明如下:
Warning
If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
这很重要,因为我们可以从您提供的数据中推断出一些重要的行为。具体来说,如果我们忽略坐标,而是查看高度和宽度值,我们会看到以下差异:
frame: (width = 134, height = 30.248210824676789)
bounds: (width = 134, height = 32)
convert: (width = 134.04199076956854, height = 29.70736933068838)
查看图像中的 UI 元素本身,我们甚至看到垂直“挤压”的文本,表明这些元素很可能以某种方式应用了变换。这可能会导致 Apple 文档中指出的上述未定义行为。正如 Apple 在他们的文档中指出的那样,当转换 属性 不是身份转换时,应该忽略 属性 的值。
不幸的是,我们无法验证这就是问题的原因,因为 UIKit
,据我了解,不共享它的源代码,但转换导致未定义的行为似乎我们可以合理得出的最佳解释。