2012-07-18 103 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]; 
}