UIView insertSubview atIndex可移动子视图的奇怪行为

时间:2018-12-05 03:01:09

标签: ios objective-c uiview subview

我有一个UIView,在这种情况下,它具有4个子视图。我希望能够更改子视图的顺序,但似乎无法使用

 [UIView insertSubview: atIndex:]

在一种特定情况下,如果我调用它将项目从索引2移动到索引1,则会将其放置在索引0。 这是调试器的输出:

(lldb) po self.subviews
<__NSArrayM 0x600003084f30>(
<ViewA: 0x7fb075cee4c0; frame = (20 12; 399.5 35.32); ...>,
<ViewB: 0x7fb075cf1b60; frame = (20 59.32; 399.5 27.5); ...>,
<ViewC: 0x7fb075cef2c0; frame = (20 98.82; 399.5 67); ...>,
<ViewD: 0x7fb075cfa750; baseClass = UIButton; frame = (20 177.82; 399.5 35); ...>)

(lldb) po self.subviews[2]
<ViewC: 0x7fb075cef2c0; frame = (20 98.82; 399.5 67); ...>

(lldb) po [self insertSubview:self.subviews[2] atIndex:1]
(lldb) po self.subviews
<__NSArrayM 0x600003085020>(
<ViewC: 0x7fb075cef2c0; frame = (20 98.82; 399.5 67); ...>,
<ViewA: 0x7fb075cee4c0; frame = (20 12; 399.5 35.32); ...>,
<ViewB: 0x7fb075cf1b60; frame = (20 59.32; 399.5 27.5); ...>,
<ViewD: 0x7fb075cfa750; baseClass = UIButton; frame = (20 177.82; 399.5 35); ...>)

如您所见,我试图将ViewC移至ViewA之后,但它却移至它之前。 如果我改用

[UIView insertSubView: aboveSubview:]

它工作正常。

我尝试在插入之前删除视图,但这给了我相同的结果。这很奇怪,我感觉这里缺少UIView的基本部分。 我可以接受这种解决方法,但是我真的更希望了解为什么它不起作用。

[更新] 事实证明,这是必不可少的一点信息。我有一个额外的CALayer,用于突出显示父视图。因此,如果我禁用此CALayer,则一切正常。 我可能是错的,但这意味着insertSubviews实际上会移动CALayers。这是否意味着self.subviews只是一个帮助函数,用于基于self.layer.sublayers获取与CALayers关联的UIView?无论如何,我找到了罪魁祸首,而且看来我对子视图的CALayers的理解肯定存在缺陷。

1 个答案:

答案 0 :(得分:4)

这很有趣。

UIView只是CALayer的包装,它提供了手势处理等功能。我们在屏幕上真正看到的是层树。似乎我们传递给insertSubview:atIndex:的index参数是层树中视图层的索引,这会引起混淆。插入子视图后,将根据视图的衬层相对于其他子视图的位置来排列subviews数组。

在您的情况下,我假设您的突出显示层位于索引0,这就是为什么当您在索引1插入子视图时它会位于subviews数组中的0位置的原因,因为它的支持层实际上位于所有其他视图的底层子视图”和您用来突出显示的CALayer上方。