I have cloned a project in Swift however the project has all been done programmatically (without the use of interface builder). The app uses a Parse PFLogin and PFSign up.
I would like to use a UITabBarController (in interface builder) to manage transitions of the views. Below is the code for my didFinishLaunchingWithOptions in the AppDelegate:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
setupParse()
setupLayer()
//* Show View Controller
controller = LoginViewController()
controller.layerClient = layerClient
// Register for push
self.registerApplicationForPushNotifications(application)
self.window!.rootViewController = UINavigationController(rootViewController: controller)
self.window!.backgroundColor = UIColor.whiteColor()
self.window!.makeKeyAndVisible()
return true
}
Is setting the root view controller the same as setting as initial view controller?
What would be the best way to change this code to set the UITabBarController shown in my interface builder as the root.
Any help would be much appreciated.
Thanks
Marc
You want to set the initial UIViewController from within the storyboard. You can do this by pointing the arrow at your desired view controller:
You can also do this from within the view controller's attribute inspector, by selecting the "Is Initial View Controller?" checkbox.
You can then remove the UIWindow code from the didFinishLaunchingWithOptions function.
Related
Short question:
How can I launch and make a UITabBarController be the rootViewController of my app after starting with a Storyboard?
Long question:
I'm not a swift expert, but I managed to create a complete app using XIBs from the beginning. Now I need my app to start with a Storyboard as a new requirement to post updates to the appstore from 01/07/2020, but I never used it to build my views. It was easy to modify my app to have my Storyboard as an entry point, but the problem is that my initial view today is a TabController, and I don't know how to navigate from my initial Storyboard to my TabController.
My AppDelegate today works something like this:
var window: UIWindow?
func application(_application: UIApplication, didFinishLauchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
// initiate UINavigationControllers and UITabBarController here...
tabController.viewController = [nav1, nav2, nav3, nav4]
tabController.modalPresentationStyle = .fullScreen
self.window!.rootViewController = tabController
self.window!.makeKeyAndVisible()
}
All my attempts ended with a white screen after showing my Storyboard without showing my TabBar.
One of these attempts was this:
override func loadView() {
super.loadView()
// initiate tabController the same way I did in the AppDelegate
UIApplication.shared.keyWindow?.rootViewController = tabController
}
Check the value "Is initial View Controller" for it.
So, I'm trying to instantiate my view controller programmatically using storyboard references.
I've put this code in the AppDelegate:
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialController: WelcomePageViewController = mainStoryboard.instantiateViewController(withIdentifier: "WelcomePageViewController") as! UITabBarController
window?.rootViewController = initialController
window?.makeKeyAndVisible()
return true
}
And set this inside my view controller's storyboard:
However when I run the application, only a black screen is shown and this message:
"Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?"
I've used this exact code in other apps and it works just fine.
I've tried to clean build folder, to run it on an actual device and to create and instantiate a different storyboard file but nothing worked.
Open your Main.storyboard file and find WelcomePageViewController. When it’s selected, go to the attributes inspector and check the box marked Is Initial View Controller.
You should see a right-facing arrow appear to the left of WelcomePageViewController, showing that it’s your storyboard’s entry point.
Now you're all set to go!!!
Ok So i think here is something you can do if it suits:
set entry point to the navigation controller
class that navigation controller with a file like rootNavigationVC.swift which is subclass of UINavigationController
now in didLoad() you can set it's viewController or push one based on your condition
trust me its better than coding in AppDelegate.swift which never worked for me.
I wish to create and present a view over each view controller in my app allowing users to interact with it or the view controllers beneath it. I want the view to always appear on top of whatever view I may present or segue to.
I have a custom UIView that appears when users tap a table view cell. Within the didSelectRowAt tableView function I have tried:
(UIApplication.shared.delegate as! AppDelegate).window?.addSubview(self.subView!)
and
self.view.addSubview(self.subView!)
Both function similarly with the view appearing over the current View controller and allowing users to interact with the table still. But when I present a new ViewController the subView disappears as it has not been added to the new View.
Subclass UIWindow, and override addSubview() to make sure your overlay view is always on top:
weak var overlay: MyOverlayView!
override func addSubview(_ view: UIView) {
if let overlay = view as? MyOverlayView {
self.overlay = overlay
super.addSubview(overlay)
} else {
self.insertSubview(view, belowSubview: overlay)
}
}
You must make sure the app delegate uses your custom class as the app's main window, and not the superclass UIWindow. For this, remove the "Main storyboard file base name" entry from your Info.plist and instead instantiate the main window manually in your AppDelegate:
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: MyCustomWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
self.window = MyCustomWindow(frame: UIScreen.main.bounds)
// 1. Add your overlay view to the window
// (...)
// 2. Load your initial view controller from storyboard, or
// instantiate it programmatically
// (...)
window?.makeKeyAndVisible()
return true
}
Note: I haven't tested this code. Let me know in the comments if there's a problem.
I have a root view that shows up when I first start my app. The root view has a button that when pressed opens another view controller that should have a nav bar at the top with an (add) navigation item. The problem is when I set the root view as the root view in app delegate, my other controller (that opens from a button) fails to show the nav bar with the nav item.
Heres what I mean:
When App Delegate is set to
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let firstviewController = FirstViewController()
let navController = UINavigationController(rootViewController: firstviewController)
let core = CoreViewController()
window?.rootViewController = navController
return true
}
The navigation controls and navbar all show up but the CoreViewController (the view with the button) fails to show up first as the root controller.
How can first view controller keep its NavControls while have CoreViewController launch first as the root screen?
View Controller with Button
When View Controller is a Nav Controller
When developing an app, if I only want to test one screen, say, the third tab of a tab view, how would I make the app navigate there on start up?
I think a good solution is use a UI test to automatically navigate to the correct place in the app. Pausing on a breakpoint at the end of the test leaves the app to be played with manually.
rootViewController of window property in AppDelegate will be the first view controller shown on screen. you can make it by programming or using storyboard
by programming:
if NavigationController is the rootViewController of your window, put your own viewController in the first place (index at 0) of NavigationController's viewControllers which is an array. it will be on screen by default.
customNavigationController.viewControllers = [yourViewController]
or simply set your viewController to the rootViewController to the window property in appDelegate
AppDelegate.swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
// window?.rootViewController = CustomTabBarViewController()
// customViewController will show on screen by default.
window?.rootViewController = CustomViewController()
window?.makeKeyAndVisible()
return true
}
by interface builder:
check your viewControlelr's attributes inspector panel, and check "is Initial View Controller" option, then you can see a simple arrow attached to this view controller.
or:
add identifier to your viewController, and fetch it from storyBoard, then set it to the rootViewController of the window object in appDelegate
let testController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "testController") as! TestController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = testController