UIView 的 bounds.origin 啥时候不是 (0, 0)?

Posted

技术标签:

【中文标题】UIView 的 bounds.origin 啥时候不是 (0, 0)?【英文标题】:When would a UIView's bounds.origin not be (0, 0)?UIView 的 bounds.origin 什么时候不是 (0, 0)? 【发布时间】:2011-12-09 22:54:35 【问题描述】:

什么时候 UIView 的bounds.origin 不是(0, 0)

这一段对我很有帮助:

重要!边界 X 和 Y,原点,用于在 看法。对于示例 X+5,将 5pix 移动到帧原点的左侧 表示将此视图中的所有内容绘制到帧的左侧 5pix 起源。它对自己没有任何作用,它是被它吸引的东西 会受到影响。

但它只描述了我自己设置了bounds.origin 的值的情况。bounds.origin != (0, 0) 的值还有哪些其他情况?

【问题讨论】:

【参考方案1】:

视图的框架决定了它在超级视图中的位置。视图的边界决定了它的子视图位置。这意味着,如果你改变视图的边界,它的位置不会改变,但它的所有子视图的位置都会改变。

正的宽度和高度就像你从左上角到右下角画一个视图,而负值是从右下角到左上角。所以

frame1 = CGRectMake(100, 100, -50, -50) 

完全相同
frame2 = CGRectMake(50, 50, 50, 50). 

事实上,如果你用 frame1 初始化一个视图,它会自动更改到 frame2。

但视图中的bounds.origin 并不相同。 Bounds.origin 表示您“绘制”视图的点,因此所有子视图帧都将从该点开始。

例如,在横向 iPhone 6 中,我们有:

UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 275, 275)];
leftView.backgroundColor = [UIColor greenColor];
[self.view addSubview:leftView];

UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(667-50, 375-50, -275, -275)];
rightView.backgroundColor = [UIColor blueColor];
[self.view addSubview:rightView];

我们得到了:

我们会发现rightView的frame自动变成了正值,也就是(342,50,275,275),但是它的bounts.origin = (-275,-275)

我们添加子视图:

UIView *leftSubview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
leftSubview.backgroundColor = [UIColor grayColor];
[leftView addSubview:leftSubview];
UIView *rightSubview= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
rightSubview.backgroundColor = [UIColor grayColor];
[rightView addSubview:rightSubview];

所以边界使得rightView的子视图跟随我们初始化rightView的原点。

如果我们改变rightView的边界等于leftView: rightView.bounds = leftView.bounds; 那么两个subView的位置是一样的,我们就丢失了rightView的宽高为负数的信息。

我们改变 leftView 而不是 rightView 的边界: CGRect bounds = leftView.bounds; bounds.origin = CGPointMake(50, 50); leftView.bounds = bounds;

我们可以看到,它的 subview 的 frame.origin 被 bounds.origin 偏移了(使用减号,而不是加号)。

总结:

    view.bounds 确定其所有子视图的位置(由 bounds.origin 偏移),而bounds 不会影响其在其父视图中的位置。

    如果你初始化一个负宽高的视图,它会自动变为正数(不会改变位置),但它的 bounds.origin 表示你开始“绘制”视图的点.

【讨论】:

很好的答案。 “边界”令人困惑,因为它给人的印象是 x,y 是为其设置的视图的位置。为什么他们将视图的维度与其本地来源联系起来? 很好的答案,感谢您抽出额外的时间来解释事物以及图片表示。 +1。【参考方案2】:

当 contentOffset 不是 (0, 0) 时,UIScrollView 的 bounds.origin 不会是 (0, 0)。

【讨论】:

【参考方案3】:

如果你用负宽度/高度初始化视图,bounds.origin 将为负值。 例如,如果你这样做了

UIView* v = [[UIView alloc] initWithFrame:CGRectMake(5, 5, -10, -20)];

框架是:

origin = 
  x = -5, 
  y = -15
, 
size = 
  width = 10, 
  height = 20

界限:

origin = 
  x = -10, 
  y = -20
, 
size = 
  width = 10, 
  height = 20

中心:

x = 0, 
y = -5

自己试试吧!

【讨论】:

这毫无意义。它等于表达式“相对于自身的坐标系原点不等于”,这是错误的,没有意义。 你为什么要创建一个负的宽度和高度? 不管有没有道理,这些都是你执行这段代码得到的结果。 从 x、y 坐标中减去负宽度和高度。它不会阻止或拒绝负长度,而是自行调整。至少我是这么理解的【参考方案4】:

(再次编辑,因为我在接受后无法删除我的原始答案 - 这归功于 ian,他在下面发布了更全面的答案:)

在大多数情况下,这不会发生。如果您使用负宽度和/或高度初始化视图,您将获得一个具有负 X 宽度和/或负 Y 高度的原点。

【讨论】:

我不认为这是真的。我见过一些情况,系统中与自动调整大小相关的东西似乎给我留下了一个原点不是 0.0 的界限。在我自己的代码中,我从来没有设置过界限,所以让它突然出现一个非零数字真是令人震惊。 @KendallHelmstetterGelner 同意。当我有一个导航控制器对我的 UIScrollView 进行一些调整大小时,这发生在我身上(我认为是“调整滚动视图插图”设置的结果)。

以上是关于UIView 的 bounds.origin 啥时候不是 (0, 0)?的主要内容,如果未能解决你的问题,请参考以下文章

添加为页脚视图时,UIButton 没有响应

创建一个拉伸的半圆

获取屏幕上的某个控件相对位置,尤其是tableviewcell上的某一个控件的相对位置

问题理解 CALayer 几何。需要帮助

新冠疫情啥时结束

linux的/etc下,passwd文件名后面跟的“+”号或“-”号是啥意思?啥时会出现【passwd+】文件?多谢