NavigationControllers mają stosy ViewController do zarządzania i ograniczone przejścia animacji.
Dodanie kontrolera widoku jako widoku podrzędnego do istniejącego kontrolera widoku wymaga przekazywania zdarzeń do kontrolera widoku podrzędnego, co jest trudne w zarządzaniu, obarczone niewielkimi irytacjami i generalnie wydaje się być złym hackiem podczas implementacji (Apple odradza również robiąc to).
Przedstawienie modalnego kontrolera widoku ponownie umieszcza kontroler widoku na drugim i chociaż nie ma problemów z przekazywaniem zdarzeń opisanych powyżej, tak naprawdę nie zamienia kontrolera widoku, ale układa go w stos.
Scenorysy są ograniczone do iOS 5 i są prawie idealne, ale nie można ich używać we wszystkich projektach.
Czy ktoś może przedstawić SOLID CODE EXAMPLE na sposobie zmiany kontrolerów widoku bez powyższych ograniczeń i pozwala na animowane przejścia między nimi?
Bliski przykład, ale bez animacji: jak używać wielu kontrolerów widoku niestandardowego systemu iOS bez kontrolera nawigacji
Edycja: użycie kontrolera nawigacji jest w porządku, ale muszą istnieć animowane style przejść (nie tylko efekty slajdów), a wyświetlany kontroler widoku musi zostać całkowicie zamieniony (nie ułożony w stos). Jeśli drugi kontroler widoku musi usunąć inny kontroler widoku ze stosu, oznacza to, że nie jest wystarczająco hermetyzowany.
Edycja 2: iOS 4 powinien być podstawowym systemem operacyjnym dla tego pytania, powinienem był to wyjaśnić, wspominając o scenorysach (powyżej).
źródło
Odpowiedzi:
EDYCJA: Nowa odpowiedź, która działa w każdej orientacji. Oryginalna odpowiedź działa tylko wtedy, gdy interfejs jest w orientacji pionowej. Są to animacje przejścia widoku b / c, które zastępują widok z innym widokiem, muszą występować z widokami co najmniej o poziom poniżej pierwszego widoku dodanego do okna (np
window.rootViewController.view.anotherView
.).Zaimplementowałem prostą klasę kontenera, którą nazwałem
TransitionController
. Możesz go znaleźć na https://gist.github.com/1394947 .Na marginesie wolę implementację w oddzielnej klasie b / c, która jest łatwiejsza do ponownego wykorzystania. Jeśli tego nie chcesz, możesz po prostu zaimplementować tę samą logikę bezpośrednio w delegacie aplikacji, eliminując potrzebę stosowania
TransitionController
klasy. Logika, której potrzebujesz, byłaby jednak taka sama.Użyj go w następujący sposób:
W delegacie aplikacji
Aby przejść do nowego kontrolera widoku z dowolnego kontrolera widoku
EDYCJA: Oryginalna odpowiedź poniżej - działa tylko w orientacji pionowej
Przyjąłem następujące założenia dla tego przykładu:
Masz przypisany kontroler widoku jako
rootViewController
oknoPo przełączeniu do nowego widoku chcesz zamienić bieżący viewController na viewController będący właścicielem nowego widoku. W dowolnym momencie aktywny jest tylko bieżący kontroler viewController (np. Przydzielony).
Kod można łatwo zmodyfikować, aby działał inaczej, kluczową kwestią jest animowane przejście i kontroler pojedynczego widoku. Upewnij się, że nie zachowujesz kontrolera widoku poza przypisaniem go do
window.rootViewController
.Kod do animacji przejścia w delegacie aplikacji
Przykładowe użycie w kontrolerze widoku
źródło
TransitionController.m
naUIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
, ale używałem tego tylko w najnowszej wersji iOS, więc przetestuj uważnie.Możesz użyć nowego systemu powstrzymywania ViewController firmy Apple. Aby uzyskać bardziej szczegółowe informacje, obejrzyj film z sesji WWDC 2011 „Implementing
UIViewController
Containment”.Nowość w systemie iOS5,
UIViewController
Containment umożliwia posiadanie elementu nadrzędnego viewController i wielu zawartych w nim kontrolerów podrzędnych. Tak działa UISplitViewController. W ten sposób możesz ułożyć kontrolery widoku w nadrzędnym, ale dla twojej konkretnej aplikacji używasz tylko rodzica do zarządzania przejściem z jednego widocznego viewController do drugiego. Jest to zatwierdzony przez Apple sposób robienia rzeczy i animowania z jednego widoku dziecka. Kontroler jest bezbolesny. Dodatkowo możesz używać wszystkich różnychUIViewAnimationOption
przejść!Ponadto dzięki UIViewContainment nie musisz się martwić o bałagan związany z zarządzaniem podrzędnymi kontrolerami widoku podczas wydarzeń orientacyjnych. Możesz po prostu użyć poniższego, aby upewnić się, że parentViewController przekazuje zdarzenia rotacji do elementu podrzędnego viewControllers.
Możesz wykonać następujące lub podobne czynności w metodzie viewDidLoad swojego rodzica, aby skonfigurować pierwszy element childViewController:
wtedy, gdy trzeba zmienić element podrzędny viewController, wywołujesz coś w następujący sposób w ramach elementu nadrzędnego viewController:
Tutaj zamieściłem pełny przykładowy projekt: https://github.com/toolmanGitHub/stackedViewControllers . Ten inny projekt pokazuje, jak używać funkcji
UIViewController
Containment na niektórych różnych typach kontrolerów danych wejściowych, które nie zajmują całego ekranu. Powodzeniaźródło
[self.currentViewController willMoveToParentViewController:nil];
przed przejściem?OK, wiem, że pytanie brzmi bez użycia kontrolera nawigacyjnego, ale nie ma powodu, aby tego nie robić. OP nie odpowiadał na komentarze na czas, abym położył się spać. Nie głosuj na mnie. :)
Oto jak otworzyć bieżący kontroler widoku i przejść do nowego kontrolera widoku za pomocą kontrolera nawigacji:
źródło
Ponieważ właśnie natknąłem się na ten konkretny problem i wypróbowałem różne warianty wszystkich wcześniej istniejących odpowiedzi na ograniczony sukces, opublikuję, jak ostatecznie go rozwiązałem:
Jak opisano w tym poście na temat niestandardowych segmentów , tworzenie niestandardowych segmentów jest naprawdę łatwe. Są również bardzo łatwe do podłączenia w Interface Builder, utrzymują relacje w IB widoczne i nie wymagają dużego wsparcia ze strony kontrolerów widoku źródła / miejsca docelowego.
W powyższym poście znajduje się kod iOS 4, który zastępuje bieżący kontroler widoku z góry w stosie navigationController na nowy, używając animacji wsuwania od góry.
W moim przypadku chciałem, aby nastąpiła podobna zmiana, ale z
FlipFromLeft
przejściem. Potrzebowałem też tylko wsparcia dla iOS 5+. Kod:Z RAFlipReplaceSegue.h:
Z RAFlipReplaceSegue.m:
Teraz, przytrzymaj klawisz Ctrl i przeciągnij, aby ustawić dowolny inny rodzaj płynności, a następnie utwórz z niego niestandardowe przejście i wpisz nazwę niestandardowej klasy płynnej, et voilà!
źródło
–performSegueWithIdentifier:sender:
metody UIViewController .Walczyłem z tym przez długi czas i jeden z moich problemów jest tutaj wymieniony , nie jestem pewien, czy miałeś ten problem. Ale oto, co poleciłbym, jeśli musi działać z iOS 4.
Najpierw utwórz nową
NavigationController
klasę. Tutaj wykonamy całą brudną robotę - inne klasy będą mogły „czysto” wywoływać metody instancji, takie jakpushViewController:
i takie. W twoim.h
:Tablica kontrolerów widoku podrzędnego będzie służyć jako magazyn dla wszystkich kontrolerów widoku w naszym stosie. Automatycznie przekazalibyśmy dalej cały obrót i zmianę rozmiaru kodu z
NavigationController
widoku do plikucurrentController
.Teraz w naszej realizacji:
Teraz można wdrożyć swój własny
pushViewController:
,popViewController
i takie, używając tych wywołań metod.Powodzenia i mam nadzieję, że to pomoże!
źródło
viewWillAppear
,viewDidAppear
i takie.Wypróbuj ten kod.
Ten kod zapewnia przejście z kontrolera widoku do innego kontrolera widoku, który ma kontroler nawigacji.
źródło