Выполнить Segue в ViewDidLoad
В iOS 5 у меня есть раскадровка с модальным контроллером представлений, которую я бы хотел отобразить, если ее первый пользователь в приложении, после чего я бы хотел пропустить этот контроллер представления.
Я установил ключ NSDefault, чтобы обработать это, но когда я проверяю, установлен ли этот параметр, а затем используйте функцию performSegueWithIdentifier для запуска segue, ничего не происходит. Если я поставлю этот сегу за кнопкой, он отлично работает...
Ответы
Ответ 1
Я ответил на аналогичный вопрос, когда разработчик хотел показать экран входа в начале. Я собрал для него пример кода, который можно скачать здесь. Ключом к решению этой проблемы является вызов вещей в нужное время, если вы хотите отобразить этот новый контроллер представления, вы увидите в примере, что вы должны использовать что-то вроде этого
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:YES];
}
У меня также есть объяснение того, как работают segues и раскадровки, вы можете увидеть здесь
Ответ 2
Загрузка в ViewDidLoad заставила "под-слой" мигать. Я решил это, загрузив свою раскадровку программно. Таким образом, в разделе Target/Main Storyboard - оставьте это поле пустым. Затем добавьте следующее:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Load Main App Screen
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
HomeScreenVC *homeScreenVC = [storyboard instantiateInitialViewController];
self.window.rootViewController = homeScreenVC;
[self.window makeKeyAndVisible];
// Load Login/Signup View Controller
UIViewController *mainLoginVC = [storyboard instantiateViewControllerWithIdentifier:@"MainLoginVC"];
[mainLoginVC setModalPresentationStyle:UIModalPresentationFullScreen];
[homeScreenVC presentModalViewController:mainLoginVC animated:NO];
return YES;
}
Ответ 3
Проблема заключается в том, что вы добавляете второе представление в иерархию до того, как будет добавлено первое. Попробуйте ввести код:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// Present your modal from here
}
После вызова [super viewDidAppear]
у вас есть полностью загруженное представление для изменения.
Ответ 4
Нет основной проблемы с выполнением segues в viewDidLoad (после вызова супер, конечно).
Проблема заключается в выполнении segues, прежде чем окно приложения станет видимым.
UIViewController, который вы хотите отобразить, является частью основной раскадровки, поэтому она загружается в память, прежде чем приложение начнет запускать ее код в делегате приложения. В вашем случае viewDidLoad вызывается iOS, прежде чем ваше окно приложения получит сообщение: MakeKeyAndVisible.
Важная часть - видимость.
Выполнение segue в иерархии представлений, в которой окно не видно, ничего не делает!
Вы можете попробовать сделать что-то вроде этого:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// The window initialized with hidden = YES, so in order to perform the segue we need to set this value to NO.
// After this action, the OS will add the window.rootViewController view as a subview of the window.
self.window.hidden = NO;
[self.window.rootViewController performSegueWithIdentifier:_IDENTIFIER_ sender:self.window.rootViewController];
// Now that the window is not hidden, we must make it key.
[self.window makeKeyWindow];
return YES;
}
Ответ 5
ОБНОВЛЕНИЕ: это решение больше не работает в iOS 8.
Правильный способ решения вашей проблемы состоит в том, чтобы вызвать контроллер сеанса segue/present modal в методе делегирования приложения applicationDidBecomeActive:
или в обработчике уведомлений UIApplicationDidBecomeActiveNotification
.
Фактическая документация Apple сообщает о том же:
Если ваше приложение ранее было в фоновом режиме, вы также можете использовать его для обновления пользовательского интерфейса вашего приложения.
Это решение имеет то преимущество, что оно работает с основным механизмом загрузки раскадровки, поэтому вам не нужно ничего загружать вручную и писать ненужный код.
Я использую это решение успешно в iOS 6.1, 7.0 и 7.1, и он должен работать и на iOS 5.
Ответ 6
Вот как я это сделал в SWIFT. Это также скрывает контроллер просмотра.
override func viewWillAppear(animated: Bool) {
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
if (isloggedIn != false) {
self.view.hidden = true
} else {
self.view.hidden = false
}
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let isloggedIn = prefs.objectForKey("isLoggedIn") as? Bool
if (isloggedIn != false) {
println("this should work")
self.performSegueWithIdentifier("Login", sender: self)
}
}
Ответ 7
Для Swift:
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("toView2", sender: self)
}
Для Swift 3:
DispatchQueue.main.async {
self.performSegueWithIdentifier("toView2", sender: self)
}
Ответ 8
Swift 3
override func viewWillAppear(_ animated: Bool) {
if authPreference.isExist() == true {
self.view.isHidden = true
} else {
self.view.isHidden = false
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
if authPreference.isExist() == true {
navigateToSegue()
}
}
Ответ 9
У меня была та же проблема. Прежде чем найти этот вопрос, я решил эту проблему, используя async в основном потоке. Таким образом, этот код будет вызываться потоком пользовательского интерфейса сразу после создания представления.
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:@"segueAlbums" sender:self];
});
Этот код можно вызвать в методе viewDidLoad
.
Ответ 10
Обновлено для Swift 3
Ниже приведен фрагмент кода, который позволяет загружать какой-либо viewController. В моем случае это был TabBarController, если у пользователя был действительный токен входа в facebook. Преимущество этого решения над другим решением Swift 3 заключается в том, что оно мгновенно без мерцания экрана.
func applicationDidBecomeActive(_ application: UIApplication) {
if FBSDKAccessToken.current() != nil {
self.window?.rootViewController?.present((self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "TabBarController"))!, animated: false, completion: nil)
}
}
Ответ 11
Лучшее решение для этого:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self performSegueWithIdentifier:@"NameSegue" sender:self];
}