Facebook統合チュートリアルを実行しています。ユーザーが現在の状態の有効なトークンを持っている場合はMainViewViewControllerを表示し、それ以外の場合はLoginViewControllerを表示します。
MainViewAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// To-do, show logged in view
} else {
// No, display the login page.
[self showLoginView];
}
return YES;
}
- (void)showLoginView
{
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
LoginViewController* loginViewController = [mainstoryboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
[self.window.rootViewController presentViewController:loginViewController animated:YES completion:NULL];
}
コンソールエラー:
Warning: Attempt to present <LoginViewController: 0xb492fd0> on <MainViewViewController: 0xb1bd820> whose view is not in the window hierarchy!
NavigationControllerを使用したくありません。
同じ問題がありました。 この質問 への回答に基づいて、[self.window makeKeyAndVisible]
直前 presentViewController:animated:completion:
、そしてそれは私のためにそれを修正しました。
あなたの場合、showLoginViewは
- (void)showLoginView
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:loginViewController animated:YES completion:NULL];
}
Window.rootViewControllerからモーダルView Controllerを表示すると、同じ警告が生成され、効果がない場合があります。このようなView Controllerの階層の例:
呼び出し中
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:[UIViewController new] animated:YES completion:nil];
この正確な警告が発生します(iOS6と7 Simの両方でテスト済み)
解決策:rootViewControllerを使用する代わりに、提示された一番上のものを使用します。
UIViewController *topRootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topRootViewController.presentedViewController)
{
topRootViewController = topRootViewController.presentedViewController;
}
[topRootViewController presentViewController:yourController animated:YES completion:nil];
Stepan Generalovの答え は、Swift 3で私にとって正しいものでした!!!
もちろん新しい構文などを使用するため、ここにコピーします。
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "MainApp") as! ViewController
var topRootViewController: UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!
while((topRootViewController.presentedViewController) != nil){
topRootViewController = topRootViewController.presentedViewController!
}
topRootViewController.present(vc, animated: true, completion: nil)
この場合、「MainApp」はメインビューコントローラの識別子です。
他の方法もありますが、アプリのさまざまな部分を開くために異なるURLスキームを使用する必要がある場合は、AppDelegateで処理する必要があります。
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {}
メソッドでは、url
が文字列として何であるかを確認してから、上記のコードを実行するか、他のView Controller(withIdentifier
)の異なる識別子を持つ同様のコードを実行するかを決定できます。
In Swift 3:-
let storyboard = UIStoryboard(name: "Login", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "LoginViewController")
window?.makeKeyAndVisible()
window?.rootViewController?.present(viewController, animated: true, completion: nil)
ケースでは、ストーリーボードを使用していないとき。まず、YourViewControllerを作成する必要があります。 Go File-> New-> File ...(またはshortCut-command + N)
その後、Cocoa Touch Classを選択します。 [次へ]をクリックするか、Enter
ViewControllerの名前を入力して、[次へ]をクリックします
#import "AppDelegate.h"
#import "YourViewController.h"
@interface AppDelegate ()
@end
@implementaion AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Init window
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
[self.window makeKeyAndVisible];
// Init YourViewController
YourViewController *viewController = [[YourViewController alloc] init];
// Init YourNavigationController
UINavigationController *navigationContoller = [[UINavigationController alloc] initWithRootViewController: viewController];
// Set rootViewController
self.window.rootViewController = navigationContoller;
return YES;
}
@end
Swift 3/4の例
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//1-st step
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
//2-nd - create a window root controller, and create a layout
let layout = UICollectionViewFlowLayout()
window?.rootViewController = UINavigationController(rootViewController: HomeController(collectionViewLayout: layout))
return true
}