Swift 5 e Xcode 11
Quindi in xCode 11 la soluzione per finestre non è più valida all'interno di appDelegate. Lo hanno spostato su SceneDelgate. Puoi trovarlo nel file SceneDelgate.swift.
Noterai che ora ha un var window: UIWindow?regalo.
Nella mia situazione stavo usando un TabBarController da uno storyboard e volevo impostarlo come rootViewController.
Questo è il mio codice:
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 }
}
Assicurati di aggiungere questo al metodo di scena corretto come ho fatto qui. Tieni presente che dovrai impostare il nome identificativo per tabBarController o viewController che stai utilizzando nello storyboard.

Nel mio caso lo stavo facendo per impostare un stateController per tenere traccia delle variabili condivise tra le visualizzazioni delle schede. Se desideri fare la stessa cosa aggiungi il seguente codice ...
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()
}
Nota: usa semplicemente le tue variabili o qualunque cosa tu stia cercando di tenere traccia, invece, ho elencato le mie come esempio in struct tdfvariables.
In ciascuna vista di TabController aggiungere la seguente variabile membro.
class SettingsViewController: UIViewController {
var stateController: StateController?
.... }
Quindi in quegli stessi file aggiungere quanto segue:
extension SettingsViewController: StateControllerProtocol {
func setState(state: StateController) {
self.stateController = state
}
}
Ciò consente di evitare l'approccio singleton al passaggio di variabili tra le viste. Ciò consente facilmente il modello di iniezione delle dipendenze che è molto meglio a lungo termine rispetto all'approccio singleton.