Swift 5 et Xcode 11
Ainsi, dans xCode 11, la solution de fenêtre n'est plus valide à l'intérieur de appDelegate. Ils l'ont déplacé vers SceneDelgate. Vous pouvez le trouver dans le fichier SceneDelgate.swift.
Vous remarquerez qu'il a maintenant un var window: UIWindow?
cadeau.
Dans ma situation, j'utilisais un TabBarController à partir d'un storyboard et je voulais le définir comme rootViewController.
Voici mon 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 }
}
Assurez-vous d'ajouter ceci à la méthode de scène correcte comme je l'ai fait ici. Notez que vous devrez définir le nom d'identifiant du tabBarController ou du viewController que vous utilisez dans le storyboard.
Dans mon cas, je faisais cela pour définir un stateController pour garder une trace des variables partagées parmi les vues d'onglets. Si vous souhaitez faire la même chose, ajoutez le code suivant ...
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()
}
Remarque: utilisez simplement vos propres variables ou tout ce que vous essayez de suivre à la place, je viens de lister les miennes comme exemple dans tdfvariables struct.
Dans chaque vue de TabController, ajoutez la variable membre suivante.
class SettingsViewController: UIViewController {
var stateController: StateController?
.... }
Ensuite, dans ces mêmes fichiers, ajoutez ce qui suit:
extension SettingsViewController: StateControllerProtocol {
func setState(state: StateController) {
self.stateController = state
}
}
Cela vous permet d'éviter l'approche singleton pour passer des variables entre les vues. Cela permet facilement le modèle d'injection de dépendances qui est bien meilleur à long terme que l'approche singleton.