在appdelegate中设置初始viewcontroller - swift

Abu*_*lim 133 ios

我想从appdelegate设置初始viewcontroller.我找到了一个非常好的答案,但它是在Objective C中,我很难在swift中实现同样的功能.

使用Storyboard以编程方式设置初始视图控制器

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    UIViewController *viewController = // determine the initial view controller here and instantiate   it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];

    self.window.rootViewController = viewController;
    [self.window makeKeyAndVisible];

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

有人能帮忙吗?

我希望初始Viewcontroller依赖于使用条件语句满足的某些条件.

Abu*_*lim 262

我使用这个线程帮助我将目标C转换为swift,并且它的工作完美.

在Swift中实例化和呈现viewController

Swift 2代码:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginSignupVC")

    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()

    return true
}
Run Code Online (Sandbox Code Playgroud)

Swift 3代码:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)

    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    let initialViewController = storyboard.instantiateViewController(withIdentifier: "LoginSignupVC")

    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()

    return true
}
Run Code Online (Sandbox Code Playgroud)

  • @rigdonmr如果应用程序将Storyboard设置为主界面,则会自动加载窗口,并将其根视图控制器设置为storyboard的初始视图控制器.如果视图控制器需要根据条件进行更改,或者应用程序没有主界面,则可以初始化"UIWindow"并以编程方式设置其根视图控制器. (7认同)
  • 这是*在appdelegate*中设置初始视图控制器的当前标准方法吗?我问,因为它看起来像是一个小小的黑客(对不起@Abs). (5认同)
  • 这里令人惊讶(但很好)的事情是以这种方式手动实例化视图控制器似乎阻止iOS实例化默认视图控制器.我可能期望两者都被加载.这种行为是否记录在某处? (2认同)
  • @MayankJain可以在Swift 3上正常工作,只需要翻译早期swift的一些代码 (2认同)

小智 42

试试这个.例如:您应该使用UINavigationController初始视图控制器.然后,您可以从故事板中将任何视图控制器设置为root.

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as UINavigationController
    let rootViewController:UIViewController = storyboard.instantiateViewControllerWithIdentifier("VC") as UIViewController
    navigationController.viewControllers = [rootViewController]
    self.window?.rootViewController = navigationController
    return true
}
Run Code Online (Sandbox Code Playgroud)

我的故事板屏幕.

  • 该应用程序在发布后显示黑屏 (3认同)

gam*_*mal 35

对于新的 Xcode 11.xxx 和 Swift 5.xx,目标设置为 iOS 13+。

对于新的项目结构,AppDelegate 不需要对 rootViewController 做任何事情。

有一个新类来处理 window(UIWindowScene) 类 -> 'SceneDelegate' 文件。

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = // Your RootViewController in here
        self.window = window
        window.makeKeyAndVisible()
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 非常赞赏。 (2认同)

Eri*_*ana 23

对于Swift 3,Swift 4:

从故事板中实例化根视图控制器:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // this line is important
        self.window = UIWindow(frame: UIScreen.main.bounds)

        // In project directory storyboard looks like Main.storyboard,
        // you should use only part before ".storyboard" as it's name,
        // so in this example name is "Main".
        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)

        // controller identifier sets up in storyboard utilities
        // panel (on the right), it called Storyboard ID
        let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController

        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()        
        return true
    }
Run Code Online (Sandbox Code Playgroud)

如果要以UINavigationControllerroot 身份使用:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // this line is important
        self.window = UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
        let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController
        let navigationController = UINavigationController.init(rootViewController: viewController)
        self.window?.rootViewController = navigationController

        self.window?.makeKeyAndVisible()        
        return true
    }
Run Code Online (Sandbox Code Playgroud)

从xib实例化根视图控制器:

它几乎相同,但不是线条

let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController
Run Code Online (Sandbox Code Playgroud)

你必须写

let viewController = YourViewController(nibName: "YourViewController", bundle: nil)
Run Code Online (Sandbox Code Playgroud)


小智 21

如果你没有使用故事板,你可以试试这个

var window: UIWindow?
var initialViewController :UIViewController?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    initialViewController  = MainViewController(nibName:"MainViewController",bundle:nil)

    let frame = UIScreen.mainScreen().bounds
    window = UIWindow(frame: frame)

    window!.rootViewController = initialViewController
    window!.makeKeyAndVisible()

    return true
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*mim 16

Swift 4.2 和 5 代码的代码:

var window: UIWindow?


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     self.window = UIWindow(frame: UIScreen.main.bounds)

     let storyboard = UIStoryboard(name: "Main", bundle: nil)

     let initialViewController = storyboard.instantiateViewController(withIdentifier: "dashboardVC")

     self.window?.rootViewController = initialViewController
     self.window?.makeKeyAndVisible()
}
Run Code Online (Sandbox Code Playgroud)

而对于Xcode 11+ and for Swift 5+

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

     var window: UIWindow?

     func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
         if let windowScene = scene as? UIWindowScene {
             let window = UIWindow(windowScene: windowScene)

              window.rootViewController = // Your RootViewController in here

              self.window = window
              window.makeKeyAndVisible()
         }
    }
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ell 14

这是接近它的好方法.此示例将导航控制器作为根视图控制器放置,并将您选择的视图控制器放在导航堆栈的底部,准备好从中推送您需要的任何内容.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
    // mainStoryboard
    let mainStoryboard = UIStoryboard(name: "MainStoryboard", bundle: nil)

    // rootViewController
    let rootViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MainViewController") as? UIViewController

    // navigationController
    let navigationController = UINavigationController(rootViewController: rootViewController!)

    navigationController.navigationBarHidden = true // or not, your choice.

    // self.window
    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    self.window!.rootViewController = navigationController

    self.window!.makeKeyAndVisible()
}
Run Code Online (Sandbox Code Playgroud)

要使此示例正常工作,您可以在主视图控制器上将"MainViewController"设置为Storyboard ID,在这种情况下,storyboard的文件名将为"MainStoryboard.storyboard".我以这种方式重命名我的故事板,因为Main.storyboard对我来说不是一个正确的名称,特别是如果你去它的子类.


Pat*_*gar 11

我是在目标上做到的 - 希望它对你有用

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

UIViewController *viewController;

NSUserDefaults *loginUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *check=[loginUserDefaults objectForKey:@"Checklog"];

if ([check isEqualToString:@"login"]) {

    viewController = [storyboard instantiateViewControllerWithIdentifier:@"SWRevealViewController"];
} else {

    viewController = [storyboard instantiateViewControllerWithIdentifier:@"LoginViewController"];
}


self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
Run Code Online (Sandbox Code Playgroud)


yoA*_*ex5 8

在 AppDelegate 中初始化 ViewController

[初始视图控制器]

禁用 Main.storyboard

General -> Deployment Info -> Main Interface -> remove `Main` 
Info.plist -> remove Key/Value for `UISceneStoryboardFile` and `UIMainStoryboardFile`
Run Code Online (Sandbox Code Playgroud)

添加故事板 ID

Main.storyboard -> Select View Controller -> Inspectors -> Identity inspector -> Storyboard ID -> e.g. customVCStoryboardId
Run Code Online (Sandbox Code Playgroud)

[上一个]
Swift 5 和 Xcode 11

延长 UIWindow

class CustomWindow : UIWindow {
    //...
}
Run Code Online (Sandbox Code Playgroud)

由 Xcode 生成的编辑 SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: CustomWindow!

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let windowScene = (scene as? UIWindowScene) else { return }

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewController = storyboard.instantiateViewController(withIdentifier: "customVCStoryboardId")

        //or if your storyboard has `Is Initial View Controller`
        let storyboard = UIStoryboard(name: String(describing: SomeViewController.self), bundle: nil)
        let initialViewController = storyboard.instantiateInitialViewController()

        window = CustomWindow(windowScene: windowScene)
        window.rootViewController = initialViewController
        window.makeKeyAndVisible()
    }

    //...
}
Run Code Online (Sandbox Code Playgroud)

[访问框架包]
[从框架中获取故事板]


p-s*_*sun 7

如果您不使用故事板。您可以以编程方式初始化主视图控制器。

斯威夫特 4

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    let rootViewController = MainViewController()
    let navigationController = UINavigationController(rootViewController: rootViewController)
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()

    return true
}
Run Code Online (Sandbox Code Playgroud)
class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .green
    }
}
Run Code Online (Sandbox Code Playgroud)

MainDeployment Info 中删除。

在此处输入图片说明


Kun*_*nal 6

我在Xcode 8和swift 3.0中做过希望它对你有用,并且它的工作完美.使用以下代码:

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {       
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let initialViewController = storyboard.instantiateViewController(withIdentifier: "ViewController")
    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()
    return true
}
Run Code Online (Sandbox Code Playgroud)

如果您使用的是导航控制器,请使用以下代码:

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.window = UIWindow(frame: UIScreen.main.bounds)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let navigationController:UINavigationController = storyboard.instantiateInitialViewController() as! UINavigationController
    let initialViewController = storyboard.instantiateViewControllerWithIdentifier("ViewController")
    navigationController.viewControllers = [initialViewController]
    self.window?.rootViewController = navigationController
    self.window?.makeKeyAndVisible()      
    return true
}
Run Code Online (Sandbox Code Playgroud)


Wad*_*ers 6

斯威夫特4:

在appDelegate.swift中,在didFinishLaunchingWithOptions()函数中添加这些行...

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Setting the Appropriate initialViewController

    // Set the window to the dimensions of the device
    self.window = UIWindow(frame: UIScreen.main.bounds)

    // Grab a reference to whichever storyboard you have the ViewController within
    let storyboard = UIStoryboard(name: "Name of Storyboard", bundle: nil)

    // Grab a reference to the ViewController you want to show 1st.
    let initialViewController = storyboard.instantiateViewController(withIdentifier: "Name of ViewController")

    // Set that ViewController as the rootViewController
    self.window?.rootViewController = initialViewController

    // Sets our window up in front
    self.window?.makeKeyAndVisible()

    return true
}
Run Code Online (Sandbox Code Playgroud)

现在,例如,当我们想要将用户驱动到登录屏幕或初始设置屏幕或返回到应用程序的主屏幕等时,我们多次执行类似这样的操作.如果您想要执行类似的操作,你可以把这一点用作叉路.

想一想.你可以在NSUserDefaults中存储一个值,例如持有userLoggedIn的布尔值和if userLoggedIn == false { use this storyboard & initialViewController... } else { use this storyboard & initialViewController... }


Bor*_*rzh 5

那么上面/下面的所有答案都会产生关于故事板中没有入口点的警告.

如果你想拥有2个(或更多)依赖于某些条件的入口视图控制器(比如conditionVariable),你应该做的是:

  • 在Main.storyboard中创建没有 rootViewController的UINavigationController ,将其设置为入口点
  • 在视图控制器中创建2(或更多)"显示"segues,为它们分配一些id,比如id1id2
  • 使用下一个代码:

    class AppDelegate: UIResponder, UIApplicationDelegate {
    
       var window: UIWindow?
    
       func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
           let navigationController = window!.rootViewController! as! UINavigationController
           navigationController.performSegueWithIdentifier(conditionVariable ? "id1" : "id2")
    
           return true
       }
    
    Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.