Swift 5 & Xcode 11
In xCode 11 ist die Fensterlösung in appDelegate nicht mehr gültig. Sie haben dies in das SceneDelgate verschoben. Sie finden dies in der Datei SceneDelgate.swift.
Sie werden feststellen, dass es jetzt ein var window: UIWindow?Geschenk hat.
In meiner Situation verwendete ich einen TabBarController aus einem Storyboard und wollte ihn als rootViewController festlegen.
Das ist mein Code:
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 }
}
Stellen Sie sicher, dass Sie dies der richtigen Szenenmethode hinzufügen, wie ich es hier getan habe. Beachten Sie, dass Sie den Bezeichnernamen für den tabBarController oder viewController festlegen müssen, den Sie im Storyboard verwenden.

In meinem Fall habe ich dies getan, um einen stateController festzulegen, der gemeinsam genutzte Variablen in den Registerkartenansichten verfolgt. Wenn Sie dasselbe tun möchten, fügen Sie den folgenden Code hinzu ...
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()
}
Hinweis: Verwenden Sie stattdessen einfach Ihre eigenen Variablen oder was auch immer Sie verfolgen möchten. Ich habe meine nur als Beispiel in der Struktur tdfvariables aufgeführt.
Fügen Sie in jeder Ansicht des TabControllers die folgende Mitgliedsvariable hinzu.
class SettingsViewController: UIViewController {
var stateController: StateController?
.... }
Fügen Sie dann in denselben Dateien Folgendes hinzu:
extension SettingsViewController: StateControllerProtocol {
func setState(state: StateController) {
self.stateController = state
}
}
Auf diese Weise können Sie den Singleton-Ansatz zum Übergeben von Variablen zwischen den Ansichten vermeiden . Dies ermöglicht leicht das Abhängigkeitsinjektionsmodell, das auf lange Sicht viel besser ist als der Singleton-Ansatz.