重新排序UIView子视图

时间:2012-07-18 20:52:33

标签: ios uiview layer subviews

在我的应用中,我正在尝试将子视图放到前面,然后将其放回原来的图层位置。代码应该非常简单:

将子视图放在前面(在我的自定义UIView类中):

[self.superview bringSubviewToFront:self];

易。我将原始z位置存储在一个名为zPosition的实例变量中。因此,-bringSubviewToFront:之前的行是:

zPosition = [self.superview.subviews indexOfObject:self];

因此,我用来将子视图放在前面的所有代码都是:

zPosition = [self.superview.subviews indexOfObject:self];
[self.superview bringSubviewToFront:self];

这样可行。问题是当我尝试将子视图放回原位时。我只是这样做:

[self.superview exchangeSubviewAtIndex:zPosition withSubviewAtIndex:
    [self.superview.subviews indexOfObject:self]];

使用此代码,如果我有两个子视图,则会发生以下情况:

假设我有视图A和视图B.视图A在视图B上方。我点击视图B,它来到前面。我再次点击视图B(它应该回到原来的位置),没有任何反应,所以它现在在视图A上。如果我现在点击视图A,它会到达前面,但是当我再次点击它时(所以它应该回到原来的z位置:在视图B)下面,它的所有兄弟视图都消失了!

有谁看到可能导致此问题的原因?

4 个答案:

答案 0 :(得分:11)

exchangeSubviewAtIndex可能会将视图放回正确的位置,但它也会在顶部交换另一个视图,这不是您开始使用的视图。您可能需要执行类似此操作而不是exchangeSubviewAtIndex:

[self retain];
UIView *superview = self.superview;
[self removeFromSuperview];
[superview insertSubview:self atIndex:zPosition];
[self release];

答案 1 :(得分:10)

无需从superview中删除:

[self.superview insertSubview:self atIndex:zPosition];

答案 2 :(得分:1)

[Swift解决方案]

正如其他人所说,没有必要删除和重新添加您的子视图。

相反,我发现最方便的方法是:

superView.insertSubview(subviewYouWantToReorder, aboveSubview: subviewWhichShouldBeBelow)

答案 3 :(得分:0)

这个问题和答案对我很有帮助。

我要求在视图堆叠的上方和下方的视图堆叠之间放置一个叠加层,我想让它保持动态。 也就是说,视图可以告诉它是否隐藏。

我使用以下算法重新排序视图。 感谢下面的AW101“无需删除视图”。

这是我的算法:

- (void) insertOverlay {

    // Remember above- and belowcounter
    int belowpos = 0, abovepos = 0;

    // Controller mainview
    UIView *mainview = [self currentMainView];

    // Iterate all direct mainview subviews
    for (UIView* view in mainview.subviews) {
        if ([self isAboveOverlay:view]) {
            // Re-insert as aboveview
            [mainview insertSubview:view atIndex:belowpos + (abovepos++)];
        }
        else {
            // Re-insert as belowview
            [mainview insertSubview:view atIndex:belowpos++];
        }
    }

    // Put overlay in between above and below.
    [mainview insertSubview:_overlay atIndex:belowpos];
}