2012-07-18 113 views
10

在我的应用程序中,我尝试将子视图放到前面,稍后将其放回原始图层位置。该代码应该是很简单的:重新排序UIView子视图

为了使子视图前(我的自定义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]]; 

使用此代码,如果我有两个子视图,这是发生了什么:

比方说,我有一个观点,并查看B.查看A是上述观点B.我点击视图B,它来到前面。我再次点击视图B(它应该回到原来的位置),并且没有任何反应,所以它现在处于视图A中。如果我现在点击视图A,它会到达前面,但是当我再次点击它时(所以它应该回到原来的z位置:在视图B)下面,所有的兄弟姐妹视图都消失了!

有没有人看到有什么可能导致这个问题?

+0

也许你可以用假的,空的子视图顶部开始。然后你与那个子视图来回切换。不是最优雅的,我知道...... – 2012-07-18 21:13:23

回答

11

exchangeSubviewAtIndex可能会将视图重新放在正确的位置,但它也会交换顶部的另一个视图,这不会是您开始使用的视图。您可能需要做这样的事情,而不是exchangeSubviewAtIndex的:

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

调用'[self removeFromSuperview]'导致'self'被释放,因为一旦它从它的超级视图中被移除,什么都不再拥有它了。 – 2012-07-18 22:32:18

+0

也许你可以把它委托给superview(和/或负责这个层次结构的视图控制器)呢? – 2012-07-18 23:52:51

+0

尝试暂时保留自己。我已经更新了我的答案。 – AW101 2012-07-19 08:00:22

9

没有必要从上海华盈删除:

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

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]; 
}