У меня есть раскадровка, настроенная с рабочим логином и контроллером основного представления, последний является контроллером представления, к которому пользователь переходит в случае успешного входа в систему. Моя цель - немедленно показать главный контроллер представления, если аутентификация (хранящаяся в цепочке ключей) прошла успешно, и показать контроллер представления входа, если аутентификация не удалась. По сути, я хочу сделать это в своем AppDelegate:
// url request & response work fine, assume success is a BOOL here
// that indicates whether login was successful or not
if (success) {
// 'push' main view controller
} else {
// 'push' login view controller
}
Я знаю о методе performSegueWithIdentifier: но этот метод является методом экземпляра UIViewController, поэтому его нельзя вызвать из AppDelegate. Как мне это сделать, используя существующую раскадровку ??
РЕДАКТИРОВАТЬ:
Начальный контроллер представления Storyboard теперь является контроллером навигации, который ни к чему не подключен. Я использовал различие setRootViewController:, потому что MainIdentifier - это UITabBarController. Тогда вот как выглядят мои строки:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
BOOL isLoggedIn = ...; // got from server response
NSString *segueId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:segueId];
if (isLoggedIn) {
[self.window setRootViewController:initViewController];
} else {
[(UINavigationController *)self.window.rootViewController pushViewController:initViewController animated:NO];
}
return YES;
}
Предложения / улучшения приветствуются!
[[self window] makeKeyAndVisible]
в делегате вашего приложения и 2. вызывать application: didFinishLaunchingWithOptions:, прежде чем пытаться выполнить условные переходы. Предполагается, что UIApplicationMain () отправляет сообщение makeKeyAndVisible, но делает это только после того, как didFinish ... Параметры: Finishes. Дополнительные сведения см. В разделе «Координация усилий между контроллерами представления» в документации Apple.Я удивлен некоторыми предлагаемыми здесь решениями.
На самом деле нет необходимости в фиктивных контроллерах навигации в вашей раскадровке, скрытии представлений и запуске переходов на viewDidAppear: или любых других хаках.
Если в вашем plist-файле не настроена раскадровка, вы должны сами создать и окно, и корневой контроллер представления :
Если раскадровка будет настроена в PLIST в приложении, окно и корневой контроллер представления уже будет настройка приложение времени: didFinishLaunching: называюсь, и makeKeyAndVisible будет вызываться окном для вас.
В этом случае все еще проще:
источник
ЕСЛИ точка входа вашей раскадровки не является
UINavigationController
:ЕСЛИ точка входа вашей раскадровки - это
UINavigationController
замена:с участием:
источник
appHasLaunchedOnce ? secondViewControllerIdentifier : firstViewControllerIdentifier;
В вашем методе AppDelegate
application:didFinishLaunchingWithOptions
передreturn YES
строкой добавьте:Замените
YourStartingViewController
на имя вашего фактического первого класса контроллера представления (тот, который вы не хотите обязательно отображать) иYourSegueIdentifier
фактическое имя перехода между этим начальным контроллером и тем, с которого вы действительно хотите начать (тот, который находится после перехода ).Оберните этот код в
if
условное выражение, если вы не хотите, чтобы это всегда происходило.источник
Учитывая, что вы уже используете раскадровку, вы можете использовать ее, чтобы представить пользователю MyViewController, настраиваемый контроллер ( немного уваривая ответ followben ).
В AppDelegate.m :
Строка, переданная в instantiateViewControllerWithIdentifier, относится к идентификатору раскадровки, который можно установить в построителе интерфейса:
Просто оберните это логикой по мере необходимости.
Однако, если вы начинаете с UINavigationController, этот подход не даст вам элементов управления навигацией.
Чтобы «перескочить» от начальной точки контроллера навигации, настроенного с помощью конструктора интерфейсов, используйте следующий подход:
источник
Почему бы не иметь экран входа в систему, который появляется первым, проверить, вошел ли уже пользователь, и сразу же перейти на следующий экран? Все в ViewDidLoad.
источник
Быстрая реализация того же:
Если вы используете в
UINavigationController
качестве точки входа в раскадровкеисточник
Это решение, которое сработало на iOS7. Чтобы ускорить начальную загрузку и не выполнять ненужную загрузку, у меня есть полностью пустой UIViewcontroller с именем «DUMMY» в моем файле раскадровки. Тогда я могу использовать следующий код:
источник
Я предлагаю создать новый MainViewController, который является корневым контроллером представления контроллера навигации. Для этого просто удерживайте control, затем перетащите соединение между Navigation Controller и MainViewController, выберите «Relationship - Root View Controller» из приглашения.
В MainViewController:
Не забудьте создать переходы между MainViewController с контроллерами представления Home и Login. Надеюсь это поможет. :)
источник
Попробовав много разных методов, я смог решить эту проблему следующим образом:
источник