【问题标题】:set initial viewcontroller in appdelegate - swift在 appdelegate 中设置初始视图控制器 - swift
【发布时间】:2015-01-01 10:50:25
【问题描述】:

我想从 appdelegate 设置初始视图控制器。我找到了一个非常好的答案,但是它在 Objective C 中并且我无法在 swift 中实现同样的事情。

Programmatically set the initial view controller using Storyboards

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

有人可以帮忙吗?

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

【问题讨论】:

标签: ios


【解决方案1】:

Xcode11 和 SceneDelegate 说明:

从 Xcode11 开始,由于 SceneDelegates,您很可能不应该在 AppDelegate 内执行此操作。而是从SceneDelegate 执行此操作。有关更多信息,请参阅this other answer


旧答案:

我使用这个线程来帮助我将目标 C 转换为 swift,并且它工作得很好。

Instantiate and Present a viewController in Swift

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
}

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
}

【讨论】:

  • 在 swift 2 应用程序中找不到故事板“Main”,也找不到“Storyboard.storyboard”
  • 这是当前在 appdelegate 中设置初始视图控制器的标准方法吗?我问是因为它看起来有点像黑客(对不起@Abs)。
  • @rigdonmr 如果应用程序将 Storyboard 设置为主界面,则自动加载窗口,并将其根视图控制器设置为情节提要的初始视图控制器。如果视图控制器需要根据条件进行更改,或者应用程序没有主界面,则可以初始化 UIWindow 并以编程方式设置其根视图控制器。
  • 这里令人惊讶(但很好)的是,以这种方式手动实例化视图控制器似乎会阻止 iOS 实例化默认视图控制器。我可能预计两者都会被加载。这种行为是否记录在某处?
  • @MayankJain 这适用于 Swift 3,只需要翻译早期 swift 中的一些代码
【解决方案2】:

试试这个。例如: 您应该使用UINavigationController 作为初始视图控制器。然后,您可以从情节提要中将任何视图控制器设置为 root。

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

my storyboard screen.

【讨论】:

  • 您是否为情节提要中的视图控制器设置情节提要 ID?见joxi.ru/l2ZYxZqS8JOomJ
  • 是的,已经设置好了,我认为它成功地打开了视图控制器,但它没有“显示”它。有什么想法吗?
  • 没有错误,开机后黑页
  • 我想我找到了问题所在。您应该在情节提要中选中“是初始视图控制器”。 joxi.ru/8AnNbQlhq3QOAO
  • 但我想使用条件语句更改初始视图控制器。
【解决方案3】:

对于新的 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()
    }

}

【讨论】:

  • 非常感谢。
  • 我试图在 AppDelegate 中以旧方式执行此操作,但它不起作用。它让我陷入了困境。这有很大帮助。谢谢!
【解决方案4】:

斯威夫特 3、斯威夫特 4:

将第一行改为

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

其他的都一样。

Swift 5+:

从情节提要中实例化根视图控制器:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 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 its 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 is called 'Storyboard ID'
        let viewController = storyboard.instantiateViewController(withIdentifier: "YourViewControllerIdentifier") as! YourViewController

        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()        
        return true
    }

如果你想使用UINavigationController 作为root:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 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
    }

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

几乎是一样的,但不是线条

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

你必须写

let viewController = YourViewController(nibName: "YourViewController", bundle: nil)

【讨论】:

    【解决方案5】:

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

    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
    }
    

    【讨论】:

    • 笔尖名称指的是什么?
    • @Abs nibName 是要加载以实例化视图的 nib 的名称。
    • 方向转换动画停止工作。
    • 我已经对此赞不绝口......“必须初始化窗口然后设置它的框架,必须初始化窗口然后设置它的框架,必须初始化窗口然后设置它的框架”-我自己跨度>
    【解决方案6】:

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

    对于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()
             }
        }
    }
    

    【讨论】:

    • self.window 给出错误 'AppDelegate' 类型的值没有成员 'window',有什么想法吗?
    • @JosephAstrahan 在调用它之前声明一个变量。喜欢 - var window: UIWindow?.
    • @JosephAstrahan 再次检查我的答案。我添加了变量。
    • 谢谢,帮了大忙!
    • And for Xcode 11+ and for Swift 5+ 部分对我有很大帮助。谢谢人
    【解决方案7】:

    这是处理它的好方法。此示例将导航控制器放置为根视图控制器,并将您选择的视图控制器放置在导航堆栈的底部,以便您从中推送所需的任何内容。

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

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

    【讨论】:

      【解决方案8】:

      我是在 Objective-C 中完成的。希望对你有用。

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

      【讨论】:

      • 你是如何在 storyboard 中设计视图控制器的。请帮忙。
      • 拖动视图控制器并设置身份的故事板 ID: 并访问您的视图控制器...
      • @PatelJigar 如何在 loginvc 中设置
      • 像这样调用视图控制器 UITabBarController *tbc = [self.storyboard instantiateViewControllerWithIdentifier:@"ContentViewController"]; [self presentViewController:tbc 动画:YES 完成:nil];
      【解决方案9】:

      在 AppDelegate 中初始化 ViewController

      [Initial View Controller]

      禁用Main.storyboard

      General -> Deployment Info -> Main Interface -> remove `Main` 
      Info.plist -> remove Key/Value for `UISceneStoryboardFile` and `UIMainStoryboardFile`
      

      添加情节提要 ID

      Main.storyboard -> Select View Controller -> Inspectors -> Identity inspector -> Storyboard ID -> e.g. customVCStoryboardId
      

      [previos]
      Swift 5 和 Xcode 11

      扩展UIWindow

      class CustomWindow : UIWindow {
          //...
      }
      

      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()
          }
      
          //...
      }
      

      [Access to Framework bundle]
      [Get storyboard from a framework]

      【讨论】:

      • 可以将根控制器设置为初始视图控制器 window.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
      【解决方案10】:

      如果您不使用情节提要。您可以通过编程方式初始化您的主视图控制器。

      斯威夫特 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
      }
      
      class MainViewController: UIViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              view.backgroundColor = .green
          }
      }
      

      同时从部署信息中删除Main

      【讨论】:

      • 这在 Swift 4.2、XCode 11.3、IOS 9 ~ 13.3.1 和我一起工作
      【解决方案11】:

      我在 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
      }
      

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

      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
      }
      

      【讨论】:

      • 嗨... Mayank,我在 Xcode 8 和 swift 3.0 中完成了使用此解决方案后出现的错误,因为它正在工作
      【解决方案12】:

      斯威夫特 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
      }
      

      现在,例如,当我们想要将用户引导至登录屏幕或初始设置屏幕或返回应用程序的主屏幕等时,我们经常会执行此类操作。如果您想做某事就像这样,你可以把这一点当作一个岔路口。

      考虑一下。您可以将一个值存储在 NSUserDefaults 中,例如保存一个 userLoggedIn 布尔值和 if userLoggedIn == false { use this storyboard &amp; initialViewController... } else { use this storyboard &amp; initialViewController... }

      【讨论】:

      • 它不适用于添加了 1 个 ViewController 的新项目。总是从初始视图控制器开始。 Xcode 11.2 哪里有问题?
      【解决方案13】:

      上面/下面的所有答案都产生了关于情节提要中没有入口点的警告。

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

      • 在您的 Main.storyboard 创建 UINavigationController 没有 rootViewController,将其设置为入口点
      • 在视图控制器中创建 2 个(或更多)“显示”序列,为它们分配一些 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
           }
        

      希望这会有所帮助。

      【讨论】:

      • “情节提要中没有入口点”错误是由于可以删除的项目配置造成的。转到项目 > 信息 > 自定义 iOS 目标属性并删除“主情节提要文件基本名称”属性。该警告不应再出现。
      【解决方案14】:

      这是 Swift 4 中的完整解决方案 在 didFinishLaunchingWithOptions 中实现这个

       func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      
       let isLogin = UserDefaults.standard.bool(forKey: "Islogin")
          if isLogin{
              self.NextViewController(storybordid: "OtherViewController")
      
      
          }else{
              self.NextViewController(storybordid: "LoginViewController")
      
          }
      }
      

      在 Appdelegate.swift 中的任何地方编写这个函数

        func NextViewController(storybordid:String)
      {
      
          let storyBoard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
          let exampleVC = storyBoard.instantiateViewController(withIdentifier:storybordid )
         // self.present(exampleVC, animated: true)
          self.window = UIWindow(frame: UIScreen.main.bounds)
          self.window?.rootViewController = exampleVC
          self.window?.makeKeyAndVisible()
      }
      

      【讨论】:

        【解决方案15】:

        以防万一您想在视图控制器中而不是在应用程序委托中执行此操作:只需在视图控制器中获取对 AppDelegate 的引用并使用正确的视图控制器重置它的窗口对象因为它是 rootviewController。

        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let yourVC = mainStoryboard.instantiateViewControllerWithIdentifier("YOUR_VC_IDENTIFIER") as! YourViewController
        appDelegate.window?.rootViewController = yourVC
        appDelegate.window?.makeKeyAndVisible()
        

        【讨论】:

          【解决方案16】:

          对于 swift 4.0

          didfinishedlaunchingWithOptions 方法中的 AppDelegate.swift 文件中,输入以下代码。

          var window: UIWindow?
          
          
          func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
              window = UIWindow(frame: UIScreen.main.bounds)
              window?.makeKeyAndVisible()
          
              let rootVC = MainViewController() // your custom viewController. You can instantiate using nib too. UIViewController(nib name, bundle)
              //let rootVC = UIViewController(nibName: "MainViewController", bundle: nil) //or MainViewController()
              let navController = UINavigationController(rootViewController: rootVC) // Integrate navigation controller programmatically if you want
          
              window?.rootViewController = navController
          
              return true
          }
          

          希望它能正常工作。

          【讨论】:

          • 工作..如果你还没有在 stroyboard 中设置初始 viewController 那么你必须添加 window = UIWindow(frame: UIScreen.main.bounds)
          【解决方案17】:

          Swift 5 和 Xcode 11

          所以在 xCode 11 中,窗口解决方案在 appDelegate 内不再有效。他们将其移至 SceneDelgate。您可以在 SceneDelgate.swift 文件中找到它。

          您会注意到它现在有一个var window: UIWindow?

          在我的情况下,我使用故事板中的 TabBarController 并希望将其设置为 rootViewController。

          这是我的代码:

          sceneDelegate.swift

          func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
                  // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
                  // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
                  // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
          
                  self.window = self.window ?? UIWindow()//@JA- If this scene's self.window is nil then set a new UIWindow object to it.
          
                  //@Grab the storyboard and ensure that the tab bar controller is reinstantiated with the details below.
                  let storyboard = UIStoryboard(name: "Main", bundle: nil)
                  let tabBarController = storyboard.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController
          
                  for child in tabBarController.viewControllers ?? [] {
                      if let top = child as? StateControllerProtocol {
                          print("State Controller Passed To:")
                          print(child.title!)
                          top.setState(state: stateController)
                      }
                  }
          
                  self.window!.rootViewController = tabBarController //Set the rootViewController to our modified version with the StateController instances
                  self.window!.makeKeyAndVisible()
          
                  print("Finished scene setting code")
                  guard let _ = (scene as? UIWindowScene) else { return }
              }
          

          确保像我在这里所做的那样将它添加到正确的场景方法中。请注意,您需要为您在情节提要中使用的 tabBarController 或 viewController 设置 标识符名称

          在我的例子中,我这样做是为了设置一个 stateController 来跟踪选项卡视图之间的共享变量。如果您希望做同样的事情,请添加以下代码...

          StateController.swift

          import Foundation
          
          struct tdfvars{
              var rbe:Double = 1.4
              var t1half:Double = 1.5
              var alphaBetaLate:Double = 3.0
              var alphaBetaAcute:Double = 10.0
              var totalDose:Double = 6000.00
              var dosePerFraction:Double = 200.0
              var numOfFractions:Double = 30
              var totalTime:Double = 168
              var ldrDose:Double = 8500.0
          }
          
          //@JA - Protocol that view controllers should have that defines that it should have a function to setState
          protocol StateControllerProtocol {
            func setState(state: StateController)
          }
          
          class StateController {
              var tdfvariables:tdfvars = tdfvars()
          }
          

          注意:只需使用您自己的变量或您尝试跟踪的任何变量,我只是在 tdfvariables 结构中列出了我的示例。

          在 TabController 的每个视图中添加以下成员变量。

              class SettingsViewController: UIViewController {
              var stateController: StateController?
          .... }
          

          然后在这些相同的文件中添加以下内容:

          extension SettingsViewController: StateControllerProtocol {
            func setState(state: StateController) {
              self.stateController = state
            }
          }
          

          这样做是允许您避免使用单例方法在视图之间传递变量。这很容易实现依赖注入模型,从长远来看,它比单例方法要好得多。

          【讨论】:

            【解决方案18】:

            iOS 13+

            SceneDelegate中:

            var window: UIWindow?
            
            func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options 
            connectionOptions: UIScene.ConnectionOptions) {
                guard let windowScene = (scene as? UIWindowScene) else { return }
                window = UIWindow(windowScene: windowScene)
                let vc = UIViewController() //Instead of UIViewController() we initilise our initial viewController
                window?.rootViewController = vc
                window?.makeKeyAndVisible()
            }
            

            【讨论】:

              【解决方案19】:
              I worked out a solution on Xcode 6.4 in swift. 
              
              // I saved the credentials on a click event to phone memory
              
                  @IBAction func gotobidderpage(sender: AnyObject) {
               if (usernamestring == "bidder" && passwordstring == "day303")
                      {
                          rolltype = "1"
              
              NSUserDefaults.standardUserDefaults().setObject(usernamestring, forKey: "username")
              NSUserDefaults.standardUserDefaults().setObject(passwordstring, forKey: "password")
              NSUserDefaults.standardUserDefaults().setObject(rolltype, forKey: "roll")
              
              
                          self.performSegueWithIdentifier("seguetobidderpage", sender: self)
              }
              
              
              // Retained saved credentials in app delegate.swift and performed navigation after condition check
              
              
                  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
              
              let usernamestring = NSUserDefaults.standardUserDefaults().stringForKey("username")
              let passwordstring = NSUserDefaults.standardUserDefaults().stringForKey("password")
              let rolltypestring = NSUserDefaults.standardUserDefaults().stringForKey("roll")
              
                      if (usernamestring == "bidder" && passwordstring == "day303" && rolltypestring == "1")
                      {
              
                          // Access the storyboard and fetch an instance of the view controller
                          var storyboard = UIStoryboard(name: "Main", bundle: nil)
                          var viewController: BidderPage = storyboard.instantiateViewControllerWithIdentifier("bidderpageID") as! BidderPage
              
                          // Then push that view controller onto the navigation stack
                          var rootViewController = self.window!.rootViewController as! UINavigationController
                          rootViewController.pushViewController(viewController, animated: true)
                      }
              
                      // Override point for customization after application launch.
                      return true
                  }
              
              
              
              Hope it helps !
              

              【讨论】:

                【解决方案20】:
                func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
                
                    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
                    let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                    var exampleViewController: ExampleViewController = mainStoryboard.instantiateViewControllerWithIdentifier("ExampleController") as! ExampleViewController
                
                    self.window?.rootViewController = exampleViewController
                
                    self.window?.makeKeyAndVisible()
                
                    return true
                }
                

                【讨论】:

                  【解决方案21】:

                  使用 SWRevealViewController 从 App 委托打开一个视图控制器。

                   self.window = UIWindow(frame: UIScreen.main.bounds)
                   let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
                   let swrevealviewcontroller:SWRevealViewController = storyboard.instantiateInitialViewController() as! SWRevealViewController 
                   self.window?.rootViewController = swrevealviewcontroller
                   self.window?.makeKeyAndVisible()
                  

                  【讨论】:

                    【解决方案22】:

                    Swift 5.3 + 和 iOS 13.0 +

                    在“SceneDelegate.swift”中设置您的初始 ViewController // 仅

                    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
                        
                        var window: UIWindow?
                        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
                            guard let windowScene = (scene as? UIWindowScene) else { return }
                            window = UIWindow(windowScene: windowScene)
                            setInitialViewController()
                            window?.makeKeyAndVisible()
                        }
                        
                        func setInitialViewController()  {
                            
                            // Set Story board Controller
                            /*
                             let storyboard = UIStoryboard(name: "Main", bundle: nil)
                             let vc = storyboard.instantiateViewController(withIdentifier: "ViewController")
                             */
                            
                            // Set Custom Xib
                            let vc = FrontVC(nibName: "FrontViewController", bundle: nil)
                            
                            // Navigation Controller
                            let nav = UINavigationController(rootViewController: vc)
                            nav.isNavigationBarHidden = true
                            window?.rootViewController = nav
                        }
                    

                    【讨论】:

                      【解决方案23】:

                      对于 Swift 5+

                      
                      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)
                                  let submodules = (
                                      home: HomeRouter.createModule(),
                                      search: SearchRouter.createModule(),
                                      exoplanets: ExoplanetsRouter.createModule()
                                  )
                                  
                                  let tabBarController = TabBarModuleBuilder.build(usingSubmodules: submodules)
                                  
                                  window.rootViewController = tabBarController
                                  self.window = window
                                  window.makeKeyAndVisible()
                              }
                          }
                      
                      

                      【讨论】:

                        【解决方案24】:

                        如果我的应用程序用户已经存在于钥匙串或 userdefault 中,我发现这个答案很有帮助并且非常适合我的情况。

                        https://stackoverflow.com/a/58413582/6596443

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2018-12-31
                          相关资源
                          最近更新 更多