在我的应用中,我正在尝试将子视图放到前面,然后将其放回原来的图层位置。代码应该非常简单:
将子视图放在前面(在我的自定义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)下面,它的所有兄弟视图都消失了!
有谁看到可能导致此问题的原因?
答案 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];
}