I want to insert a func(configureInitialViewController()) into willConnectTo ( so I can recall the same func in other ViewControllers )
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
configureInitialViewController()
}
func configureInitialViewController() {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
if 1>0 {
window.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: ViewController1)
} else {
window.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: ViewController2)
}
self.window = window
window.makeKeyAndVisible()
}
}
Change
func configureInitialViewController()
To
func configureInitialViewController(_ scene: UIScene)
And pass scene to it
Related
I am starting an app programmaticaly with no storyboards. When I try to make my UITabBarController the root view controller it looks like The background color should be red and the tab item should be a house. What could be the problem?
SceneDelegate code:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
window?.rootViewController = TabBarController()
window?.makeKeyAndVisible()
}
HomeViewController code:
import UIKit
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
// Do any additional setup after loading the view.
}
}
TabBarController code:
import UIKit
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
setupTab()
}
func setupTab(){
let homeVC = HomeViewController()
homeVC.tabBarItem = UITabBarItem(title: "Home", image: UIImage(named: "House"), tag: 0)
let homeNC = UINavigationController(rootViewController: homeVC)
tabBarController?.viewControllers = [homeNC]
}
}
The work for setting up the tab view controller needs to be done while you are setting up the scene in the SceneDelegate. The HomeViewContoller's viewDidLoad was never being called.
var homeNavigationController : UINavigationController!
var secondHomeNavigationController : UINavigationController!
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).
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
let tabBarController = TabBarController()
homeNavigationController = UINavigationController.init(rootViewController: HomeViewController())
secondHomeNavigationController = UINavigationController.init(rootViewController: HomeViewController())
tabBarController.viewControllers = [homeNavigationController, secondHomeNavigationController]
// let item1 = UITabBarItem(title: "Home", image: UIImage(named: "House"), tag: 0)
let item1 = UITabBarItem(tabBarSystemItem: .featured, tag: 0)
let item2 = UITabBarItem(tabBarSystemItem: .bookmarks, tag: 1)
homeNavigationController.tabBarItem = item1
secondHomeNavigationController.tabBarItem = item2
window?.rootViewController = tabBarController
window?.makeKeyAndVisible()
}
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
setupTab()
}
func setupTab(){
}
}
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
// Do any additional setup after loading the view.
}
}
I get an nearly black screen when I try to load this view. But if I add view.backgroundColor = .red it shows the color red correctly. Just the settings I did in Storyboard wont get shown.
Here is the code I used:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
guard let windowScene = scene as? UIWindowScene else { return }
window = UIWindow(windowScene: windowScene)
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
window?.rootViewController = mainStoryboard.instantiateViewController(withIdentifier: "ResultsViewController") as! ResultsViewController
window?.makeKeyAndVisible()
}
import UIKit
class ResultsViewController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .blue
}
}
You seem to have created the ResultsViewController in the storyboard. You'll have to load it from the storyboard to set it as rootViewController.
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
window?.rootViewController = mainStoryboard.instantiateViewController(withIdentifier: "ResultsViewController") as! ResultsViewController
Note: Don't forget to set the identifier for ResultsViewController as "ResultsViewController" in the storyboard.
I try to set a View as first view and get a black background. But it should be red.
This is my SceneDelegate:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
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).
guard let _ = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = MainNavigationController()
}
This is my MainNavigationController
import UIKit
class MainNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
}
}
You just need the window to be declared with windowScene initializer instead of the frame initializer.
guard let windowScene = scene as? UIWindowScene else { return }
window = UIWindow(windowScene: windowScene)
Note: Also, make sure storyboard is disabled if you're loading rootViewController programmatically.
You need to add makeKeyAndVisible() after setting root Also assign window scene to window ...
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: UIScreen.main.bounds)
window?.windowScene = windowScene
window?.rootViewController = MainNavigationController()
window?.makeKeyAndVisible()
}
I have a Router that doesn't work in new Xcode 11, it works as an appDelegate. Now I need to transition to another SCENE and I tried all issues that I found here, but it still doesn't work. Here is the code that fails to transition to the intended next scene:
class Router {
static let shared = Router()
private init() {}
private let rootViewController: UIViewController = ViewController()
func root(_ window: inout UIWindow?) {
// need to set frame or Scene
window?.makeKeyAndVisible()
window?.rootViewController = rootViewController
}
}
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
Router.shared.root(&window)
}
I need to change the initial view controller based on whether voiceover is on or not. I have tried multiple ways but I always get the same error: "Value of type 'AppDelegate' has no member 'window'"
This is what I have in my didFinishLaunchingWithOptions.
print("voiceover: \(voiceOver)") // prints if voice over is on
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewController(withIdentifier: "voiceoverViewController")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
Value of type 'AppDelegate' has no member 'window'
You have to declare a window property manually:
var window: UIWindow?
UIApplicationDelegate is just a protocol, it doesn't declare any properties for you.
You don't have to declare window variable manually
It is available in SceneDelegate file in your project
It will have pre defined method :
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions)
Example
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let windowScene = scene as? UIWindowScene {
self.window = UIWindow(windowScene: windowScene)
let initialViewController =
storyboard.instantiateViewController(withIdentifier: "voiceoverViewController")
self.window!.rootViewController = initialViewController
self.window!.makeKeyAndVisible()
}
}