web-dev-qa-db-ja.com

ViewDidLoadでセグエを実行する

IOS 5では、モーダルビューコントローラーを備えたストーリーボードがあり、ユーザーがアプリを初めて使用する場合に表示したいので、その後このビューコントローラーをスキップします。

NSDefaultキーを設定してこれを処理しますが、これが設定されているかどうかを確認してからperformSegueWithIdentifierを使用してセグエを開始しても、何も起こりません。このセグエをボタンの後ろに置くと、うまくいきます...

56
adam0101

開発者が最初にログイン画面を表示したいという同様の質問に答えました。 here をダウンロードできる彼のためのサンプルコードをまとめました。この問題を解決するための鍵は、この新しいView Controllerを表示したい場合に適切なタイミングで呼び出すことです。この例では、次のようなものを使用する必要があります

- (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でロードすると、「下層」が点滅しました。プログラムでストーリーボードを読み込むことでこれを解決しました。したがって、[ターゲット/メインストーリーボード]で、これを空白のままにします。次に、以下を追加します。

- (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

問題は、最初のビューが完全に追加される前に、2番目のビューを階層に追加していることです。コードを入れてみてください:

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

[super viewDidAppear]が呼び出された後、変更するビューが完全にロードされます。

22
NJones

ViewDidLoadでのセグエの実行には(もちろんsuperの呼び出し後)、主な問題はありません。

問題は、アプリケーションのウィンドウが表示される前にセグエを実行していることです。表示するUIViewControllerはメインストーリーボードの一部であるため、アプリがアプリデリゲートのコードの実行を開始する前にメモリに読み込まれます。あなたの場合、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では動作しません。

問題を解決する正しい方法は、applicationDidBecomeActive: appデリゲートメソッドまたはUIApplicationDidBecomeActiveNotification通知ハンドラーでセグエ/現在のモーダルビューコントローラーをトリガーすることです。

Appleのドキュメントは実際には 同じことをお勧めします

以前にアプリがバックグラウンドにあった場合は、アプリを使用してアプリのユーザーインターフェースを更新することもできます。

このソリューションには、メインストーリーボードのロードメカニズムと連携するという利点があるため、手動でロードして不要なコードを記述する必要はありません。

このソリューションはiOS 6.1、7.0、および7.1で正常に使用され、iOS 5でも動作するはずです。

10
Leon Deriglazov

これは私がスウィフトでそれをした方法です。これにより、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

Swiftの場合:

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

Swift 3:

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

Swift

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

同じ問題がありました。この質問を見つける前に、メインスレッドで非同期を使用してこの問題を解決しました。このように、このコードは、ビューを作成した直後にUIスレッドによって呼び出されます。

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

このコードは、viewDidLoadメソッドで呼び出すことができます。

1
GuillermoMP

Swiftに更新

以下のコードスニペットを使用すると、必要なviewControllerをロードできます。私の場合、ユーザーが有効なfacebookログイントークンを持っている場合、それはTabBarControllerでした。他の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

最善の解決策はこれを行うことです。

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

@ bearMountain answer for 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