I am learning how to create an iOS app without Interface Builder (i.e. storyboards, xibs, etc.). Below is the basic app delegate class I am working with. The problem is that when displayed the UIWindow does not use up the full screen of the device (see attached screenshot). This occurs on all the devices and simulators I test with. Why isn't the fullscreen being used?
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
lazy var window: UIWindow? = {
debugPrint("AppDelegate: Creating Window")
let screen: UIScreen = UIScreen.mainScreen()
let window: UIWindow = UIWindow.init(frame: screen.bounds)
window.backgroundColor = UIColor.whiteColor()
return window
}()
lazy var rootViewController: ShapesViewController = {
debugPrint("AppDelegate: Creating Root View Controller")
let rootViewController = ShapesViewController.init(nibName: nil, bundle: nil)
return rootViewController
}()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
debugPrint("AppDelegate: applicationWillEnterForeground")
window?.rootViewController = rootViewController
window?.makeKeyAndVisible()
return true
}
}
The problem turned out to be that I did not have a launch image or storyboard. For some reason without this the app defaults to the 3.5" size. Credit to this comment: A launch storyboard or xib must be provided unless the app requires full screen
This always works for me (I don't see any clear difference though). Do you mind sharing your ShapesViewController code as well?
Updated to swift 4.2
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = ViewController()
window?.makeKeyAndVisible()
return true
}
I know sounds silly but...
For a fresh project what macinjosh is saying works.
For a project of mine in Xcode 8 and swift 3, it didn't (probably because I deleted the launch screen and had to create again).
Just created new project fresh, and follow what macinjosh said. Then migrate all your files back in.
Related
This question already has answers here:
Opt out of UISceneDelegate/SwiftUI on iOS
(6 answers)
Closed 3 years ago.
I just started a new project of iOS. I created the project using xcode 11 and iOS 13. When I created project i found out that in order to set our own rootController we have to use sceneDelegate instead of AppDelegate. I want to ask if there is any possibility to use old method of setting rootControllers in AppDelegate instead of using sceneDelegate.
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window : UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let loginController: HomeViewController = HomeViewController(nibName: "HomeViewController", bundle: nil)
// let navController: UINavigationController = UINavigationController(rootViewController: loginController)
self.window?.rootViewController = loginController
self.window?.makeKeyAndVisible()
// Override point for customization after application launch.
return true
}
}
Follow these steps to use AppDelegate and opt-out for SceneDelegate
Go to Info.plist and remove Application Scene Manifest entry from Info.plist.
Remove SceneDelegate.swift
Add var window: UIWindow? in your AppDelegate.swift file
Delete the UISceneSession Lifecycle code from AppDelegate.swift
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window : UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let mainStoryBoard = UIStoryboard(name: "Main", bundle: Bundle.main)
let loginController = mainStoryBoard.instantiateViewController(withIdentifier: "HomeViewController")
self.window?.rootViewController = loginController
self.window?.makeKeyAndVisible()
return true
}
}
Make sure to give "HomeViewController" storyboardID to your view controller.
This is how your AppDelegate.swift file should look now. You are good to go!
Why don't you use the SceneDelegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(frame: windowScene.coordinateSpace.bounds)
//Make sure to do this else you won't get
//the windowScene object using UIApplication.shared.connectedScenes
self.window?.windowScene = windowScene
let storyBoard: UIStoryboard = UIStoryboard(name: storyBoardName, bundle: nil)
window?.rootViewController = storyBoard.instantiateInitialViewController()
window?.makeKeyAndVisible()
}
If you don't want to use sceneDelegate then you can remove all sceneDelegate and also remove 'Application Scene Manifest' from info.plist
set UIWindow variable
var window: UIWindow?
Make sure you have removed Application Scene Manifest this from info.plist and change the background colour of your view controller.
Your device's Dark Mode is enable if you want to remove dark mode from app add this key into your info.plist
User Interface Style = Light
My console posted this error today, [ApplicationLifecycle] UIWindows were created prior to initial application activation. This may result in incorrect visual appearance.
This has caused Application UI to not behave properly. I have never seen this before and need some insight on where to start debugging.
macOS: Catalina 10.15
XCode version: Version 11.1
I think that apps main UIWindow should be lazily initiated. Try with this:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
lazy var window: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window?.rootViewController = RootViewController() // root view controller
window?.makeKeyAndVisible()
return true
}
}
I have created a basic single view application. Using Xcode 11 now. I always build apps programatically because the tutorials I have started with never use the interface builder. For some reason not able to get the pushViewController to work. Seems to work just fine in my other projects built using Xcode 10.
In App Delegate
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow()
window?.makeKeyAndVisible()
let nc = UINavigationController(rootViewController: ViewController())
window?.rootViewController = nc
return true
}
In my viewController
#objc func handleChat(){
print("Chat pressed")
navigationController?.pushViewController(InboxViewController(), animated: true)
}
AppDelegate.swift
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let VC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as? ViewController
var Nav: UINavigationController? = nil
if let VC = VC {
Nav = UINavigationController(rootViewController: VC)
}
window?.rootViewController = Nav
return true
}
Remove SceneDelegate.swift
Goto Info.plist
Remove Application Scene Manifest
It's work for me.
I'm working on an iOS app using Xcode 6 and Swift. I'm working with storyboard, so I don't have to instantiate a NavigationController in AppDelegate.
But in my applicationDidFinishLaunching, I instantiate a controller to control Philips Hue
var window: UIWindow?
var phController:PHController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.phController = PHController()
return true
}
In this PHController I have a heartbeat function, which is checking all 10 seconds if the connection to the Philips Hue Bridge is still alive.
If not (and this could happen all the time, INDEPENDENT from where the user is currently in the app), I would like to pop a view controller (SearchForNewBridgeViewController).
The question is:
How can I pop/present modally a ViewController from PHController class instantiated when the app did finish launching?
My idea is to instantiate the PHController with the navigationController:
self.phController = PHController(self.navigationController)
But my project is as I mentioned Storyboard based, so I don't have a navigationConntroller in my AppDelegate
Ok I found a solution :)
Solution:
Instantiate my controller and give AppDelegate as argument:
var window: UIWindow?
var phController:PHController?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.phController = PHController(delegate:self)
return true
}
Initializer of PHController:
var delegate:AppDelegate?
init(delegate:AppDelegate) {
self.delegate = delegate
...
}
Present SearchForNewBridgeViewController modally from PHController:
func showSearchForNewBridge() {
let storyboard = UIStoryboard(name: "Main", bundle: nil);
var searchForNewBridgeViewController = storyboard.instantiateViewControllerWithIdentifier("searchForNewBridge") as SearchForNewBridgeViewController
var navigationController = self.delegate!.window!.rootViewController as UINavigationController
navigationController.presentViewController(searchForNewBridgeViewController, animated: true, completion: nil)
}
It's working perfectly for me
i'm using xcode 6 and they no longer have the "empty project" option when creating a new project, only a single view one...Is there an option to get it or it's gone and I need to deal with it?
Thanks a bunch
You need to deal with it, but it's easy. Start with the Single View application. Delete the storyboard and delete the reference to it in the Info.plist (so that there is no longer a main storyboard). If you like, delete the view controller class as well. Now just do everything from scratch in the app delegate's application:didFinishLaunchingWithOption:, just as you did in Xcode 5.
I'm using Swift these days, so I'll show you what a pure code app delegate launch looks like in Swift; I'm sure you can translate into Objective-C:
import UIKit
#UIApplicationMain
class AppDelegate : UIResponder, UIApplicationDelegate {
var window : UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.window = UIWindow(frame:UIScreen.mainScreen().bounds)
self.window!.rootViewController = ViewController() // or whatever you call it
self.window!.backgroundColor = UIColor.whiteColor()
self.window!.makeKeyAndVisible()
return true
}
}