it-swarm.com.ru

Выполнить Segue на ViewDidLoad

В iOS 5 у меня есть раскадровка с контроллером модального представления, которую я хотел бы отобразить, если пользователь впервые в приложении, после этого я хотел бы пропустить этот контроллер представления.

Я установил ключ NSDefault, чтобы обработать это, но когда я проверяю, установлено ли это, а затем использую executeSegueWithIdentifier, чтобы инициировать переход, ничего не происходит. Если я поставлю этот переход за кнопку, он будет работать нормально ...

56
adam0101

Я ответил на аналогичный вопрос, где разработчик хотел показать экран входа в систему при запуске. Я собрал для него пример кода, который можно скачать здесь . Ключом к решению этой проблемы является вызов вещей в нужное время. Если вы хотите отобразить этот новый контроллер представления, вы увидите в примере, что вы должны использовать что-то вроде этого

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

У меня также есть объяснение того, как работают сегменты и раскадровки, которые вы можете увидеть здесь

47
Scott Sherwood

Загрузка в 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;
}
42
bearMountain

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

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    // Present your modal from here
}

После вызова [super viewDidAppear] у вас есть полностью загруженное представление для изменения.

22
NJones

Нет принципиальной проблемы с выполнением переходов в viewDidLoad (после вызова super, конечно).

Проблема заключается в выполнении переходов до того, как окно приложения станет видимым . Контроллер UIViewControl, который вы хотите отобразить, является частью основной раскадровки, поэтому он загружается в память до того, как приложение начинает выполнять свой код в делегате приложения. В вашем случае viewDidLoad вызывается iOS до того, как окно вашего приложения получило сообщение: MakeKeyAndVisible.

Важной частью является видимость. Выполнение перехода к иерархии представлений, в которой окно не видно, ничего не делает!

Вы можете попробовать сделать что-то вроде этого:

- (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's 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;
}
11
EladWeinson

UPDATE: это решение больше не работает в iOS 8.

Правильный способ решения вашей проблемы - вызвать контроллер модального представления segue/present в методе делегата приложения applicationDidBecomeActive: или в обработчике уведомлений UIApplicationDidBecomeActiveNotification.

Документация Apple фактически советует то же самое :

Если ваше приложение ранее находилось в фоновом режиме, вы также можете использовать его для обновления пользовательского интерфейса вашего приложения.

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

Я успешно использую это решение на iOS 6.1, 7.0 и 7.1, и оно должно работать на iOS 5.

10
Leon Deriglazov

Вот как я это сделал в Swift. Это также скрывает View Controller.

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)
    }
}
5
Surge Pedroza

Для Свифта:

dispatch_async(dispatch_get_main_queue()) {
   self.performSegueWithIdentifier("toView2", sender: self)
}

Для Swift 3:

DispatchQueue.main.async {
    self.performSegueWithIdentifier("toView2", sender: self)
}
5
pbaranski

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()
    }
}
2
Jaseem Abbas

У меня такая же проблема. Прежде чем найти этот вопрос, я решил эту проблему, используя async в главном потоке. Таким образом, этот код будет вызываться потоком пользовательского интерфейса сразу после создания представления. 

dispatch_async(dispatch_get_main_queue(), ^{
        [self performSegueWithIdentifier:@"segueAlbums" sender:self];
    });

Этот код можно вызвать в методе viewDidLoad.

1
GuillermoMP

Обновлено для 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)           
    }
}
1
James Jordan Taylor

Лучшее решение - сделать это:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];    
    [self performSegueWithIdentifier:@"NameSegue" sender:self];
}
0
nhegroj

Я адаптировал @bearMountain answer для Swift 3.

func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    window = UIWindow(frame: UIScreen.main.bounds)
    let yourInitialVC: UIViewController? = storyboard.instantiateViewController(withIdentifier: "TermsVC")
    window?.rootViewController = termsVC
    window?.makeKeyAndVisible()
    return true
}
0
Nathan Barreto