Анимировать изменение контроллеров представления без использования стека контроллеров навигации, подпредставлений или модальных контроллеров?

NavigationControllers имеют стеки ViewController для управления и ограниченные переходы анимации.

Добавление контроллера представления в качестве подчиненного представления к существующему контроллеру представления требует передачи событий контроллеру подчиненного представления, что является проблемой для управления, загружается с небольшими неприятностями и в целом кажется плохим взломом при реализации (Apple также не рекомендует делая это).

Представление модального контроллера представления снова помещает контроллер представления поверх другого, и, хотя у него нет проблем с передачей событий, описанных выше, на самом деле он не меняет местами контроллер представления, а складывает его.

Раскадровки ограничены iOS 5 и почти идеальны, но не могут использоваться во всех проектах.

Может ли кто-нибудь представить ПРИМЕР ТВЕРДОГО КОДА о способе изменения контроллеров представлений без указанных выше ограничений и разрешении анимированных переходов между ними?

Близкий пример, но без анимации: Как использовать несколько контроллеров пользовательского представления iOS без контроллера навигации

Изменить: использование контроллера навигации в порядке, но должны быть анимированные стили перехода (а не просто эффекты слайдов), отображаемый контроллер представления должен быть полностью заменен (а не сложен). Если второй контроллер представления должен удалить другой контроллер представления из стека, то он недостаточно инкапсулирован.

Изменить 2: iOS 4 должна быть базовой ОС для этого вопроса, я должен был уточнить это при упоминании раскадровок (выше).


person TigerCoding    schedule 16.11.2011    source источник
comment
Вы можете выполнять пользовательские переходы анимации с помощью контроллера навигации. Если это приемлемо, удалите это ограничение из своего вопроса, и я опубликую пример кода.   -  person Richard Brightwell    schedule 16.11.2011
comment
@Richard, если он пропускает хлопоты по управлению стеком и поддерживает различные стили анимированных переходов между контроллерами представления, тогда использование контроллера навигации в порядке!   -  person TigerCoding    schedule 16.11.2011
comment
Хорошо. Я набрался терпения и выложил код. Попробуйте. Работает для меня.   -  person Richard Brightwell    schedule 16.11.2011
comment
@RichardBrightwell здесь вы сказали, что можно делать пользовательские переходы анимации между контроллерами представления с помощью контроллера навигации ... как? Можете опубликовать пример? Благодарю.   -  person Duck    schedule 05.10.2012


Ответы (6)


РЕДАКТИРОВАТЬ: новый ответ, который работает в любой ориентации. Исходный ответ работает, только когда интерфейс находится в портретной ориентации. Это анимация перехода между представлениями, которые заменяют представление с другим представлением, которое должно происходить с представлениями, по крайней мере, на уровень ниже первого представления, добавленного в окно (например, window.rootViewController.view.anotherView).

Я реализовал простой контейнерный класс, который назвал TransitionController. Вы можете найти его на странице https://gist.github.com/1394947.

Кроме того, я предпочитаю реализацию в отдельном классе b / c, который проще использовать повторно. Если вы этого не хотите, вы можете просто реализовать ту же логику непосредственно в делегате приложения, исключив необходимость в классе TransitionController. Однако логика, которая вам понадобится, будет такой же.

Используйте его следующим образом:

В вашем приложении делегат

// add a property for the TransitionController

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    MyViewController *vc = [[MyViewContoller alloc] init...];
    self.transitionController = [[TransitionController alloc] initWithViewController:vc];
    self.window.rootViewController = self.transitionController;
    [self.window makeKeyAndVisible];
    return YES;
}

Для перехода к новому контроллеру представления с любого контроллера представления

- (IBAction)flipToView
{
    anotherViewController *vc = [[AnotherViewController alloc] init...];
    MyAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
    [appDelegate.transitionController transitionToViewController:vc withOptions:UIViewAnimationOptionTransitionFlipFromRight];
}

РЕДАКТИРОВАТЬ: исходный ответ ниже - работает только для ориентации портрета

Для этого примера я сделал следующие предположения:

  1. У вас есть контроллер представления, назначенный как rootViewController вашего окна

  2. Когда вы переключаетесь на новое представление, вы хотите заменить текущий viewController на viewController, владеющий новым представлением. В любой момент активен только текущий viewController (например, выделен).

Код можно легко изменить, чтобы он работал по-другому, ключевым моментом является анимированный переход и единый контроллер представления. Убедитесь, что вы нигде не сохраняете контроллер представления, кроме назначения его window.rootViewController.

Код для анимации перехода в делегате приложения

- (void)transitionToViewController:(UIViewController *)viewController
                    withTransition:(UIViewAnimationOptions)transition
{
    [UIView transitionFromView:self.window.rootViewController.view
                        toView:viewController.view
                      duration:0.65f
                       options:transition
                    completion:^(BOOL finished){
                        self.window.rootViewController = viewController;
                    }];
}

Пример использования в контроллере представления

- (IBAction)flipToNextView
{
    AnotherViewController *anotherVC = [[AnotherVC alloc] init...];
    MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
    [appDelegate transitionToViewController:anotherVC
                             withTransition:UIViewAnimationOptionTransitionFlipFromRight];
}
person XJones    schedule 23.11.2011
comment
Да, очень мило! Это не только помогает, но и представляет собой очень простой и чистый пример кода. Большое спасибо! - person TigerCoding; 24.11.2011
comment
Разве он не вызывает у вас проблем с ландшафтом? Также: запускает ли это методы willAppear и didAppear для viewControllers? - person Felix Lamouroux; 25.11.2011
comment
Я знаю, что звонки появляются, потому что я их зарегистрировал. Я также не понимаю, почему это повлияет на изменение ориентации. Не могли бы вы объяснить, почему вы так думаете? - person TigerCoding; 26.11.2011
comment
Оказывается, @FelixLam прав. Мое решение, опубликованное здесь, работает только в портретной ориентации b / c того, как работают окна и назначенный им корневой вид. Я считаю, что это ограничение (или требование) iOS. Я придумал решение, которое работает для всех ориентаций, и добавляю его к своему ответу. Это требует использования класса контейнера, который я назвал TransitionController. Он работает аналогично UINavigationController без стека навигации. - person XJones; 26.11.2011
comment
@javy, спасибо за вопрос, разобраться в этом было забавной задачей. С другой стороны, это была большая синхронизация времени. :) Надеюсь, вы сможете это использовать. - person XJones; 26.11.2011
comment
Спасибо за все ваши усилия. Похоже, что нет реального способа изменить контроллеры представления без использования одного из методов, упомянутых в вопросе (в этом случае он теперь добавляет контроллер представления в качестве подпредставления к другому контроллеру представления). С другой стороны, портретная версия кода по-прежнему работает, по крайней мере, для приложений iPhone, поэтому, если кто-то не предложит альтернативу, я оставлю ваш как правильный ответ. - person TigerCoding; 26.11.2011
comment
Требуется, чтобы анимация происходила с представлениями на уровень ниже первого представления, добавленного в окно (например, window.rootViewController.view.anotherView). Это истинное требование. Самый простой способ сделать это - использовать в качестве контейнера специальный контроллер представления (например, TransitionController, UINavigationController и т. Д.). Вы можете скрыть этот специальный контроллер в своем делегате приложения, добавив туда методы, выполняющие переходы. Таким образом, остальные контроллеры представления могут быть реализованы, даже не зная об этом, хотя они все равно будут вызывать ваш appDelegate для выполнения перехода. - person XJones; 26.11.2011
comment
Не поймите мои комментарии неправильно, это отличный ответ, и он отлично справляется со своей задачей. Я удивлен, что спустя столько времени Apple не нашла способа сделать это. - person TigerCoding; 26.11.2011
comment
Не беспокойтесь, просто объяснял, что я узнал, работая над этим. Если бы документы Apple были немного лучше, это было бы намного проще / быстрее. - person XJones; 26.11.2011
comment
Я заметил, что новый TransitionController работает с iOS 5, но не меньше. Это потому, что представление появится, а другие методы не будут вызваны в новом контроллере представления. Он загрузит перо и отобразит его, но представление не будет вызываться в новом контроллере представления, поэтому любой код в этих методах неэффективен. - person TigerCoding; 22.04.2012
comment
Просто хотел добавить свой 2c и спасибо за такое элегантное решение. Поскольку я новичок в iOS, мне было очень трудно понять, как правильно загружать и выгружать UIViewControllers сложных сцен. Этот пост и подкласс действительно помогли мне понять, что нужно делать. Спасибо еще раз! - person Alec Sanger; 30.05.2012
comment
Отличное решение @XJones, неплохо работает в моем приложении для iPad, за исключением одной проблемы, с которой я столкнулся после первой инициализации transVC = [TransitionController ... initWithViewController: aUINavCtrlObj]; window.rootVC = transVC; представление в aUINavCtrlObj заполняется на 20 пикселей сверху (т.е. нижние 20 пикселей находятся за пределами экрана (UIWindow) во всех ориентациях), но после того, как я выполняю [transVC transitionToViewController: anotherVC], отступы исчезают. Я пробовал wantFullScreenLayout = NO в loadView TransitionController, он добавляет черную область размером 20 пикселей прямо под statusBar. - person Abduliam Rehmanius; 09.08.2012
comment
@AbduliamRehmanius: У меня была такая же проблема. Я исправил это, изменив строку 25 TransitionController.m на UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];, но я использовал это только в самой последней версии iOS, поэтому внимательно проверяйте. - person Phil Calvin; 10.08.2012
comment
@PhilCalvin действительно решает проблему, протестировано на симуляторе iOS 5, спасибо m8 :) - person Abduliam Rehmanius; 10.08.2012
comment
@XJones Это отличный подход, и я хочу, чтобы вы продолжали получать за него репутацию, поэтому я не буду переманивать его и просто изменю эту одну строчку. Тем не менее, отступы кажутся отключенными в новых версиях iOS. Сталкивались ли вы с той же проблемой, и если да, то работает ли мое решение? - person Phil Calvin; 10.08.2012
comment
@Phil У меня тоже были проблемы с заполнением, добавление этой строки self.viewController.view.frame = view.bounds; в самом конце метода loadView в TransitionController исправило это для меня. - person progrmr; 30.03.2013
comment
вы плохо справляетесь с вставкой дочернего элемента, см. github.com/xelvenone/UIViewController--Container- - person Peter Lapisu; 21.04.2013
comment
Вопрос, заданный для решения для iOS 4.x, и методы, которые вы используете в своем подклассе, требуют iOS 5.x. - person XJones; 21.04.2013
comment
Кто-нибудь знает способ выполнить такое поведение, но не вызывать viewDidAppear дважды? Спасибо! - person Frade; 13.03.2014
comment
@AwaisFayyaz Извините, но в последнее время я не занимаюсь разработкой для iOS. Stack Overflow - это здорово, но такие ответы, как этот, в данный момент хороши для конкретных версий iOS и SDK. Я уверен, что сегодня есть гораздо лучшие способы сделать это с помощью iOS 11 / Swift. Не говоря уже о том, что, вероятно, есть несколько отличных библиотек OSS. Я оставлю это сообществу SO, чтобы обновить это. Может быть, пришло время задать новый вопрос на высшем уровне? - person XJones; 20.04.2018
comment
@XJones: имеет смысл - person Awais Fayyaz; 23.04.2018

Вы можете использовать новую систему сдерживания ViewController от Apple. Для получения более подробной информации посмотрите видео сессии WWDC 2011 «Внедрение UIViewController сдерживания».

UIViewController Сдерживание, впервые появившееся в iOS5, позволяет иметь родительский viewController и несколько дочерних viewController, содержащихся в нем. Так работает UISplitViewController. Делая это, вы можете складывать контроллеры представления в родительский элемент, но для вашего конкретного приложения вы просто используете родительский элемент для управления переходом от одного видимого viewController к другому. Это одобренный Apple способ делать что-то, и анимация из одного дочернего ViewController безболезненна. Кроме того, вы можете использовать различные UIViewAnimationOption переходы!

Кроме того, с UIViewContainment вам не нужно беспокоиться, если вы не хотите, о беспорядке управления дочерними viewControllers во время событий ориентации. Вы можете просто использовать следующее, чтобы убедиться, что ваш parentViewController пересылает события вращения дочерним viewController.

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers{
    return YES;
}

Вы можете сделать следующее или подобное в родительском методе viewDidLoad для настройки первого childViewController:

[self addChildViewController:self.currentViewController];
[self.view addSubview:self.currentViewController.view];
[self.currentViewController didMoveToParentViewController:self];
[self.currentViewController.swapViewControllerButton setTitle:@"Swap" forState:UIControlStateNormal];

затем, когда вам нужно изменить дочерний viewController, вы вызываете что-то вроде следующего в родительском viewController:

-(void)swapViewControllers:(childViewController *)addChildViewController:aNewViewController{
     [self addChildViewController:aNewViewController];
     __weak __block ViewController *weakSelf=self;
     [self transitionFromViewController:self.currentViewController
                       toViewController:aNewViewController
                               duration:1.0
                                options:UIViewAnimationOptionTransitionCurlUp
                             animations:nil
                             completion:^(BOOL finished) {
                                   [aNewViewController didMoveToParentViewController:weakSelf];

                                   [weakSelf.currentViewController willMoveToParentViewController:nil];
                                   [weakSelf.currentViewController removeFromParentViewController];

                                   weakSelf.currentViewController=[aNewViewController autorelease];
                             }];
 }

Я разместил здесь полный пример проекта: https://github.com/toolmanGitHub/stackedViewControllers. В этом другом проекте показано, как использовать UIViewController Containment для некоторых различных типов входных контроллеров, которые не занимают все экран. Удачи

person timthetoolman    schedule 20.11.2011
comment
Отличный пример. Спасибо, что нашли время опубликовать код. С другой стороны, он ограничен только iOS 5. Как упоминалось в вопросе: [Раскадровки] ограничены iOS 5 и почти идеальны, но не могут использоваться во всех проектах. Учитывая, что большой процент (около 40%?) Клиентов по-прежнему используют iOS 4, цель состоит в том, чтобы предоставить что-то, что работает в iOS 4 и выше. - person TigerCoding; 21.11.2011
comment
Не следует ли вам позвонить [self.currentViewController willMoveToParentViewController:nil]; перед переходом? - person Felix Lamouroux; 25.11.2011
comment
@FelixLam - согласно документации по содержанию UIViewController, вы вызываете willMoveToParentViewController только в том случае, если вы переопределяете метод addChildViewController. В этом примере я вызываю это, но не отменяю. - person timthetoolman; 25.11.2011
comment
В демонстрации на WWDC я, кажется, помню, что они вызвали его перед вызовом запуска перехода, потому что переход не означает, что currentVC переместится в nil. В случае UITabBarController переход не изменит ни одного родительского элемента vc. Удаление из родительского объекта вызывает didMoveToParentViewController: nil, но не будет ... вызова. ИМХО - person Felix Lamouroux; 28.11.2011

Хорошо, я знаю, что в вопросе говорится без использования контроллера навигации, но нет причин не делать этого. OP не отвечал на комментарии вовремя, чтобы я мог заснуть. Не голосуйте за меня. :)

Вот как открыть текущий контроллер представления и перейти к новому контроллеру представления с помощью контроллера навигации:

UINavigationController *myNavigationController = self.navigationController;
[[self retain] autorelease];

[myNavigationController popViewControllerAnimated:NO];

PreferencesViewController *controller = [[PreferencesViewController alloc] initWithNibName:nil bundle:nil];

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.65];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:myNavigationController.view cache:YES];
[myNavigationController pushViewController:controller animated:NO];
[UIView commitAnimations];

[controller release];
person Richard Brightwell    schedule 16.11.2011
comment
Разве это не контроллеры просмотра стека? - person TigerCoding; 16.11.2011
comment
Да, потому что мы используем контроллер навигации. Тем не менее, это позволяет обойти ограничение на то, какие переходы вы можете выполнять, что, как я думал, было сутью вашего вопроса. - person Richard Brightwell; 16.11.2011
comment
Близко, но одна из больших проблем заключается в том, что в стеке есть несколько контроллеров представлений, которыми нужно управлять. Я ищу способ полностью изменить контроллеры представления. знак равно - person TigerCoding; 16.11.2011
comment
Ах. У меня тоже может быть что-то подобное ... дай мне минутку. Если нет, я удалю этот ответ. - person Richard Brightwell; 16.11.2011
comment
Хорошо, я сколотил два разных фрагмента кода. Я думаю, это сделает то, что вы хотите. - person Richard Brightwell; 16.11.2011
comment
Это работает! Однако мне любопытно ... когда вид появляется, почему он не исчезает мгновенно? Это потому, что он все еще находится в потоке пользовательского интерфейса при запуске анимации? - person TigerCoding; 16.11.2011
comment
Это потому, что я сначала сохраняю его, а затем автоматически освобождаю. Сохранение сохраняет его достаточно долго, чтобы сделать то, что нам нужно, а автозапуск позволяет ему уйти, когда мы закончим, чтобы не было утечки памяти. - person Richard Brightwell; 16.11.2011
comment
Я использую ARC, так что я предполагаю, что он применяет тот же принцип? Кроме того, прежде чем я попробую это, я проверяю счетчик стека навигационного контроллера с помощью отдельного действия кнопки: count = 1, после этого я жду несколько секунд и снова проверяю счет, и он показывает 2. Есть идеи, почему? - person TigerCoding; 16.11.2011
comment
Мне пора спать. Уже давно пора спать, иначе я был бы рад помочь дальше. Несколько напутственных мыслей: ARC - Никогда не пробовал с включенным ARC. Счетчик стека - возможно, вы можете перебрать и посмотреть, какие венчурные капиталы находятся в стеке. Надеюсь, это вам помогло. Zzzzzzzzz - person Richard Brightwell; 16.11.2011
comment
Я углублюсь в это дальше, но в стеке всегда есть два контроллера представления. Я добавил третью кнопку, вытащил стек, и счет стал 1, поэтому я рассмотрю его подробнее. - person TigerCoding; 16.11.2011
comment
Исходный контроллер представления не удаляется из стека. Его можно вручную удалить в новом контроллере представления, но тогда мы вернемся к той же проблеме управления стеком. Близко, но не совсем то, что я ищу. - person TigerCoding; 16.11.2011
comment
@RubberDuck, в ответ на ваш комментарий выше - я разместил его в этом ответе. - person Richard Brightwell; 06.10.2012

Поскольку я только что столкнулся с этой конкретной проблемой и попробовал варианты всех ранее существовавших ответов с ограниченным успехом, я опубликую, как я в конечном итоге решил ее:

Как описано в этой публикации на пользовательские сегменты, на самом деле очень легко создавать пользовательские сегменты. Их также очень легко подключить в Interface Builder, они сохраняют связи в IB видимыми и не требуют большой поддержки со стороны контроллеров представления источника / назначения segue.

В сообщении, приведенном выше, предоставляется код iOS 4 для замены текущего контроллера вида сверху в стеке navigationController новым с использованием анимации скольжения сверху.

В моем случае я хотел, чтобы произошла аналогичная замена, но с переходом FlipFromLeft. Мне также нужна была поддержка только iOS 5+. Код:

Из RAFlipReplaceSegue.h:

#import <UIKit/UIKit.h>

@interface RAFlipReplaceSegue : UIStoryboardSegue
@end

Из RAFlipReplaceSegue.m:

#import "RAFlipReplaceSegue.h"

@implementation RAFlipReplaceSegue

-(void) perform
{
    UIViewController *destVC = self.destinationViewController;
    UIViewController *sourceVC = self.sourceViewController;
    [destVC viewWillAppear:YES];

    destVC.view.frame = sourceVC.view.frame;

    [UIView transitionFromView:sourceVC.view
                        toView:destVC.view
                      duration:0.7
                       options:UIViewAnimationOptionTransitionFlipFromLeft
                    completion:^(BOOL finished)
                    {
                        [destVC viewDidAppear:YES];

                        UINavigationController *nav = sourceVC.navigationController;
                        [nav popViewControllerAnimated:NO];
                        [nav pushViewController:destVC animated:NO];
                    }
     ];
}

@end

Теперь, удерживая нажатой клавишу Control, установите любой другой вид перехода, затем сделайте его настраиваемым переходом и введите имя настраиваемого класса перехода, et voilà!

person Ryan Artecona    schedule 13.10.2012
comment
Есть ли способ сделать это программно без раскадровки? - person zakdances; 21.03.2013
comment
Насколько я знаю, чтобы использовать переход, его нужно определить и присвоить ему идентификатор в раскадровке. Вы можете вызвать переход в коде с помощью метода –performSegueWithIdentifier:sender: UIViewController. - person Ryan Artecona; 21.03.2013
comment
Вы никогда не должны вызывать viewDidXXX и viewWillXXX напрямую. - person Ben Affleck; 29.05.2014

Я долго боролся с этим, и одна из моих проблем указана здесь, я не уверен, была ли у вас такая проблема. Но вот что я бы порекомендовал, если он должен работать с iOS 4.

Во-первых, создайте новый класс NavigationController. Именно здесь мы сделаем всю грязную работу - другие классы смогут «чисто» вызывать методы экземпляра, такие как pushViewController: и тому подобное. В вашем .h:

@interface NavigationController : UIViewController {
    NSMutableArray *childViewControllers;
    UIViewController *currentViewController;
}

- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion;
- (void)addChildViewController:(UIViewController *)childController;
- (void)removeChildViewController:(UIViewController *)childController;

Массив дочерних контроллеров представления будет служить хранилищем для всех контроллеров представления в нашем стеке. Мы автоматически перенаправим весь код поворота и изменения размера из представления NavigationController в currentController.

Теперь в нашей реализации:

- (void)transitionFromViewController:(UIViewController *)fromViewController toViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL))completion
{
    currentViewController = [toViewController retain];
    // Put any auto- and manual-resizing handling code here

    [UIView animateWithDuration:duration animations:animations completion:completion];

    [fromViewController.view removeFromSuperview];
}

- (void)addChildViewController:(UIViewController *)childController {
    [childViewControllers addObject:childController];
}

- (void)removeChildViewController:(UIViewController *)childController {
    [childViewControllers removeObject:childController];
}

Теперь вы можете реализовать свои собственные pushViewController:, popViewController и тому подобное, используя эти вызовы методов.

Удачи, и я надеюсь, что это поможет!

person aopsfan    schedule 23.11.2011
comment
Опять же, мы должны прибегнуть к добавлению контроллеров представлений в качестве подвидов существующих контроллеров представлений. Конечно, это то, что делает существующий контроллер навигации, но это означает, что мы, по сути, должны переписать его и все его методы. На самом деле нам следует избегать распространения viewWillAppear и подобных методов. Я начинаю думать, что нет чистого способа сделать это. Тем не менее, я благодарю вас за то, что вы нашли время и усилия! - person TigerCoding; 23.11.2011
comment
Я думаю, что с этой системой добавления и удаления контроллеров представления по мере необходимости это решение избавляет вас от необходимости пересылать эти методы. - person aopsfan; 23.11.2011
comment
Вы уверены? Раньше я аналогичным образом менял местами контроллеры представлений, и мне всегда приходилось пересылать сообщения. Вы можете подтвердить обратное? - person TigerCoding; 23.11.2011
comment
Нет, я не уверен, но я предполагаю, что, если вы удаляете представления контроллеров представлений по мере их исчезновения и добавляете их по мере их появления, это должно автоматически запускать viewWillAppear, viewDidAppear и т. Д. - person aopsfan; 23.11.2011

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UINavigationController *viewController = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:@"storyBoardIdentifier"];
viewController.modalTransitionStyle = UIModalTransitionStylePartialCurl;
[self presentViewController:viewController animated:YES completion:nil];

Попробуйте этот код.


Этот код дает переход от контроллера представления к другому контроллеру представления, имеющему контроллер навигации.

person Deepak Kumar Sahu    schedule 07.06.2016