I'm trying to start a new Swift project. This is my first time trying to create the views programatically. However it doesn't even look like my controller is being loaded? All I see is the launch screen and then a black screen when I load it onto the simulator.
This is my AppDelegate:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
NSLog("zrrrzz") // <------------------------------ Prints properly
self.window?.rootViewController = self.rootViewController()
return true
}
private func rootViewController() -> UIViewController {
NSLog("zzz") // <---------------------------------- Does not print ????
return MapViewController.init()
}
}
MapViewController:
import UIKit
class MapViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var label = UILabel(frame: CGRectMake(0, 0, 200, 21))
label.center = CGPointMake(160, 284)
label.textAlignment = NSTextAlignment.Center
label.text = "I am a test label"
self.view.backgroundColor = UIColor.whiteColor()
self.view.addSubview(label)
NSLog("heyyyy!!") //<------------------------------ Also doesn't print ??
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Am I missing a step? I don't see any warnings / errors when I start the simulator
In the line:
self.window?.rootViewController = self.rootViewController()
If the window property is nil, it will not execute your self.rootViewController() call. You can read more about calling methods with optional chaining in the documentation for details.
If you are trying to create your initial user interface in code, you will need to create a UIWindow instance and assign it to self.window. This is done for you automatically when using a Storyboard.
Disclaimer: I haven't written this code in a few versions of iOS, so this may not be exactly correct, but it will get you going in the right direction:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let applicationFrame = UIScreen.mainScreen().applicationFrame
let window = UIWindow(frame: applicationFrame)
window.rootViewController = self.rootViewController()
window.makeKeyAndVisible()
self.window = window
return true
}
Related
I am trying to implement bottom navigation bar for my iOS application. However, when I am creating tabBarItem, it is not showing on TabBar. TabBar is displaying correctly. I cannot figure out where is the problem, any help will be very appreciated.
If any additional information is required, please give me a sign. My code (simplified):
AppDelegate:
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = TabBarController()
return true
}
}
TabBarController:
class TabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let homeController = HomeController()
let navigationController = UINavigationController(rootViewController: homeController)
navigationController.title = "Home"
navigationController.tabBarItem.image = UIImage(named: "icon")
viewControllers = [homeController]
}
}
HomeController:
class HomeController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.tabBar.isHidden = false
}
}
EDIT:
I removed not crucial parts of the code, like isLoggedIn() function call, mentioned in the comments and changed MainNavigationController to TabBarController.
According to Matts answer I also changed this line in a TabBarController (but still bar item is not showing for some reason):
viewControllers = [navigationController]
The problem is this line:
viewControllers = [homeController]
homeController is not navigationController. So what happened to navigationController? Nothing. It vanished in a puff of smoke. You created navigationController but then you threw it away.
So nothing you say about navigationController and its configuration (including its tab bar item) has any effect; it is not in the interface (or anywhere else).
This is my complete test code (based on your code):
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = MainNavigationController()
return true
}
}
class MainNavigationController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
let homeController = HomeController()
let navigationController = UINavigationController(rootViewController: homeController)
navigationController.tabBarItem.title = "MyCoolTitle"
viewControllers = [navigationController] // not [homeController]
}
}
class HomeController: UIViewController {
}
I am trying to call delegate function in AppDelegate, but seems like it never get invoked.
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,appdelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if let navigationController = window?.rootViewController, let
viewController = navigationController.childViewControllers.first as? ViewController {
viewController.delegate = self
}
// Override point for customization after application launch.
return true
}
func callfromDelegte(indicator: UIActivityIndicatorView) {
indicator.stopAnimating()
}
ViewController-:
import UIKit
protocol appdelegate:class {
func callfromDelegte(indicator:UIActivityIndicatorView)
}
class ViewController: UIViewController {
#IBOutlet weak var indicator: UIActivityIndicatorView!
weak var delegate:appdelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
indicator.startAnimating()
indicator.hidesWhenStopped = true
}
#IBAction func rotateAction(_ sender: UIButton) {
if delegate != nil{
delegate?.callfromDelegte(indicator: indicator)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Delegate is always nil, it never goes inside function. What is that i don't
now about delegates yet? How does Google GIDSignInDelegate and its delegate functions get called inside AppDelegate from controller class? I know it might be very stupid question but I would still like to know.Thanks
Ok it worked as i have not embeded my controller with navigationController. So it was not going inside if let. It worked simply like this-:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// if let navigationController = window?.rootViewController, let
// viewController = navigationController.childViewControllers.first as? ViewController {
// viewController.delegate = self
// }
// Override point for customization after application launch.
let controller = window?.rootViewController as! ViewController
controller.delegate = self
return true
}
You cannot create the Viewcontroller object directly and set the delegate inside your app delegate. You need to access the Viewcontroller object first because it is the inside the rootViewController so you need to implement like this
if let navigationController = window?.rootViewController, let
viewController = navigationController.childViewControllers.first as? ViewController {
viewController.delegate = self
}
You can try to get AppDelegate instance from shared application. Hope it will help
This is Swift 3
#IBAction func rotateAction(_ sender: UIButton) {
let delegate = UIApplication.shared.delegate as? AppDelegate
delegate?.callfromDelegte(indicator: indicator)
}
So as per title, I'm trying to present a UITableViewController from a UITabBarController. If you look at the video I've attached, on the third tab, it presents a view controller modally. Which is what I want to achieve.
https://vid.me/B0oy
I've been searching all day for a solution, and I yet I've tried them, but it doesn't work.
This is currently how I do it. I add this line of code in the view controller of my first tab.
self.tabBarController?.delegate = UIApplication.sharedApplication().delegate as? UITabBarControllerDelegate
And this is inside my AppDelegate.
class AppDelegate: UIResponder, UIApplicationDelegate, UITabBarControllerDelegate {
var window: UIWindow?
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {
if viewController is YourViewController {
if let newVC = tabBarController.storyboard?.instantiateViewControllerWithIdentifier("YourVCStoryboardIdentifier") {
tabBarController.presentViewController(newVC, animated: true, completion: nil)
return false
}
}
return true
}
func setStatusBarBackgroundColor(color: UIColor) {
guard let statusBar = UIApplication.sharedApplication().valueForKey("statusBarWindow")?.valueForKey("statusBar") as? UIView else {
return
}
statusBar.backgroundColor = color
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
setStatusBarBackgroundColor(UIColor.lightGrayColor())
return true
}
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?.backgroundColor = UIColor.whiteColor()
self.window?.makeKeyAndVisible()
let vc = ViewController()
vc.tabBarItem = UITabBarItem(...)
...
let tabbar = UITabBarController()
tabbar.setViewControllers([...,vc,...], animated: false)
self.window?.rootViewController = tabbar
tabbar.selectedIndex = 2
return true
}
}
class ViewController: UIViewController {
override func loadView() {
super.loadView()
self.view.backgroundColor = UIColor.yellowColor()
//self.automaticallyAdjustsScrollViewInsets = false;
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
}
}
I am not using a story board.
The above causes the ViewControllers view to extend below the tab bar. How can i stop this?
I've tried setting the views frame to
CGRectMake(0, 0, self.view.frame.width, self.view.frame.height - tabBarController.view.frame.height))
but that did not work.
You can use the edgesForExtendedLayout property of UIViewController to set which edges to extend under navigation bars. If you don't want any, you can simply say:
self.edgesForExtendedLayout = .None
For Swift 5 or above
self.edgesForExtendedLayout = []
I try to assign a value to a view controller from AppDelegate.swift without success.
My controller is named DestinationsViewController, and its id in Main.storyboard is destinationsID. DestinationsController is embed in a Navigation Controller. The objet I want to change is named "label". This is the code:
if let destinationsViewController = storyBoard.instantiateViewControllerWithIdentifier("destinationsID") as? DestinationsViewController {
if let label = destinationsViewController.label{
label.text = "Super!"
}
else{
println("Not good 2")
}
}
else {
println("Not good 1")
}
Unfortunately, I get the message: "Not good 2". This is not good :-(
Thank you.
import UIKit
class DestinationsViewController: UIViewController {
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Ok, here's how you can do it. However, if you change the structure of your storyboard then this may break.
First, in DestinationsViewController, you need to set a variable that will hold the text because we're setting the text before the view is rendered. Therefore, the label will not exist yet. When the view loads, it'll set the label.
class DestinationsViewController: UIViewController {
#IBOutlet weak var label: UILabel!
var labelText = String()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
label.text = labelText
}
Now, in the AppDelegate, we set the variable that will set the label when the view loads.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
// assuming inital view is tabbar
let tabBarController = self.window?.rootViewController as UITabBarController
let tabBarRootViewControllers: Array = tabBarController.viewControllers!
// assuming first tab bar view is the NavigationController with the DestinationsViewController
let navView = tabBarRootViewControllers[0] as UINavigationController
let destinationsViewController = navView.viewControllers[0] as DestinationsViewController
destinationsViewController.labelText = "Super!"
return true
}
EDIT
After re-reading your last comment, I realized you want to set the label at some point after the app has already been running. You can just move the code in func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool to where you need it. Then you can also set the label directly, because the view has been loaded.
// assuming inital view is tabbar
let tabBarController = self.window?.rootViewController as UITabBarController
let tabBarRootViewControllers: Array = tabBarController.viewControllers!
// assuming first tab bar view is the NavigationController with the DestinationsViewController
let navView = tabBarRootViewControllers[0] as UINavigationController
let destinationsViewController = navView.viewControllers[0] as DestinationsViewController
if let label = destinationsViewController.label{
label.text = "Super DUper!"
}
else{
println("Not good 2")
}