2012-07-18 12 views
10

W mojej aplikacji próbuję przenieść widok z przodu do przodu, a następnie umieścić go z powrotem do pierwotnej pozycji warstwy później. Kod powinien być dość prosty:Zmiana kolejności UIView subviews

Aby wnieść podrzędny do przodu (w moim niestandardowej klasy UIView):

[self.superview bringSubviewToFront:self]; 

łatwe. Przechowuję oryginalną pozycję z w zmiennej instancji o nazwie, zgadłeś, zPosition. Tak więc, zanim -bringSubviewToFront: linia jest:

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

tak, cały kod używam przynieść mój podrzędny do przodu jest:

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

To działa tak jak powinno. Problem polega na tym, że próbuję umieścić subview z powrotem tam, gdzie był. Jestem po prostu w ten sposób:

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

Używając tego kodu, jeśli mam dwie subviews, to co się dzieje:

Powiedzmy mam przejrzeć i zobaczyć B. Widok A jest powyżej widoku B. Widzę widok B, dochodzi do przodu. Stukam ponownie w widok B (powinien powrócić do miejsca, w którym był), i nic się nie dzieje, więc jest teraz w widoku A. Jeśli teraz dotknę widoku A, pojawi się on z przodu, ale kiedy dotknę go ponownie (tak powinno być powrócić do pierwotnej pozycji z: poniżej widoku B), wszystkie jego widoki z rodzeństwa znikają!

Czy ktoś widzi przyczynę tego problemu?

+0

Może zacząć od manekina, pustej podrzędny na górze. Potem wymieniasz się z tym podglądem. Nie najbardziej eleganckie, wiem ... –

Odpowiedz

11

exchangeSubviewAtIndex może również umieścić widok z powrotem we właściwym miejscu, ale również zamienić widok na górze, co nie będzie tym, od czego zacząłeś. Być może trzeba zrobić coś takiego zamiast exchangeSubviewAtIndex:

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

Wywołanie '[self removeFromSuperview]' powoduje, że 'self' jest dealloc'd, ponieważ po usunięciu z jego superwizji nic już go nie ma. –

+0

Być może zamiast tego możesz przekazać to do superview (i/lub kontrolera widoku odpowiedzialnego za tę hierarchię)? –

+0

Spróbuj zachować samowystarczalność. Zaktualizowałem swoją odpowiedź. – AW101

9

Nie ma potrzeby, aby usunąć z SuperView:

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

0

To pytanie było bardzo pomocne dla mnie.

Musiałem umieścić nakładkę między widokiem, które widoki są powyżej i poniżej nakładki, i chciałem zachować dynamikę. Oznacza to, że widok może powiedzieć, że jest ukryty lub nie.

Użyłem następującego algorytmu do zmiany kolejności widoków. Dzięki AW101 poniżej dla "Nie trzeba usuwać widoku".

Oto mój algorytm:

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