How to open popup from appdelegate? - swift

I have some assignment to make and I am struggling.
I have to open a modal popup at the start of an application but when I try to load my popup view my outlets are always nil, I tried a couple of different ways to load the view and its outlets are always nil.
Any suggestions?
Here I post some code
func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = FirstLaunchViewController()
}
This is my appDelegate.
class StartNavViewController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
perform(#selector(showPopUp), with: nil, afterDelay: 0.01)
}
#objc func showPopUp(){
let first = FirstLaunchViewController()
present(first, animated: true, completion: nil)
}
}
This is my starting navigation controller from which I am trying to load my FirstLaunchVC. I also tried preparing and performing a segue which resulted the exact same = outlets are nil.
In the FirstLaunchVC I set some values to my outlets in the viewdidload method, if needed I can post some code for more clarity.
I am fairly new to Swift so be as accurate as possible. Thank you very much in advance.

If your vc is inside storyboard
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "VCID") as! FirstLaunchViewController
window?.rootViewController = vc
window?.makeKeyAndVisible()

Related

Set NavigationBarController to rootViewController

I try to use MVC pattern, where my NavigationController instantiates and controls all my views and the corresponding view switches. To achieve this, I just instantiate my navigationController and set it as rootViewController in the app delegate.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let navigationController: NavigationController = (mainStoryboard.instantiateViewController(withIdentifier: "navigationController") as! NavigationController)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}
In the viewDidLoad() function of my NavigationController class, I just instantiate my first "real" view with myTableViewController and push it in front.
override func viewDidLoad() {
super.viewDidLoad()
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
self.myTableViewController = mainStoryboard.instantiateViewController(withIdentifier: "myTableViewController") as? MyTableViewController
self.pushViewController(myTableViewController!, animated: true)
}
Although everything works fine, I get the console warning:
Failed to instantiate the default view controller for
UIMainStoryboardFile 'Main' - perhaps the designated entry point is
not set?
I think this warning occurs, because the navigationController is not a "real" ViewController... But how can I fix it without instantiate MyTableView() in App delegate?
Please check your Storyboard set as Initial View Controller.

How to redirect to home screen upon going to background or resuming to the foreground

I just have a quick question regarding app life cycles and programming in Swift. I am trying to return to home screen whenever a user goes to the background. For instance, if a user receives a call or push home button, the app should go back to the main screen it started from instead of where it left off.
func applicationWillEnterForeground(_ application: UIApplication) {
guard let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(
withIdentifier: "main") as? MainViewController else { return }
self.window?.rootViewController?.present(vc, animated: true, completion: nil)
}
Above is the code I have in appDelegate, but somehow it gives an error: Attempt to present ... on ... whose view is not in the window hierarchy!"
Please help me out. Thank you very much!!
Instead of presenting over current rootViewController you need to forget about the last rootViewController. And also it is great to forget about the existing window. Use the code:
func applicationWillEnterForeground(_ application: UIApplication) {
guard let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(
withIdentifier: "main") as? UINavigationController else {
print("NIL VC")
return
}
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = vc
self.window?.makeKeyAndVisible()
}

Swift - how to load a xib file from a view controller in the story board?

I have a MainViewController.swift and it is connected to a Xib File (called MainViewController). The MainViewController is connected to a MenuViewController.swift and its Xib(called MenuViewController). The MainViewController calls the MenuViewContoller using the following code,
override func viewDidLoad() {
super.viewDidLoad()
...
menuBtn.addTarget(self, action: #selector(callMenuModal), forControlEvents: .TouchUpInside)
....
}
func callMenuModal() {
let menuVC = MenuViewController()
menuVC.delegate = self
menuVC.modalPresentationStyle = .OverCurrentContext
presentViewController(menuVC, animated: false, completion: nil)
}
.......
func backFromMenu() {
self.dismissViewControllerAnimated(true, completion: nil)
}
...
...
My friends have made a story board with a lot of Segues and ViewControllers.
I have to now load my .xib file and its corresponding view controller when a button is pressed from a ViewController on the story board. I have looked high and low for a solution and could not find one.
Previously I called my xib directly from the AppDelegate so I didn't have to do any thing. I had only one view controller in the story board and an app delegate for the whole app, the code I used in the delegate is as given below,
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
let mainViewController = MainViewController(nibName: "MainViewController", bundle: nil)
window?.rootViewController = mainViewController
window?.makeKeyAndVisible()
return true
}
........rest of app delegate....
But I don't know how to load that xib file, from a different view controller in the storyboard or a button press(IBAction) from a ViewController.
You can't directly segue to your MainViewController from the storyboard. But you can load it and display it, just like you did your app delegate.
How do you want to display MainViewController? Push it onto a navigation stack, present it modally, something else? I'm going to assume you're using a UINavigationController and you want to push it onto the stack.
In your friend's UIViewController class, add a method to load and present your MainViewController:
func presentMainViewController() {
let mainVC = MainViewController(nibName:"MainViewController", bundle:nil)
self.navigationController.pushViewController(mainVC, true);
// you could present it another way, such as:
// self.presentViewController(mainVC, true, nil)
// to present it as a modal
}
Solved it...it was right in front of my eyes, guess i had to ask the question to write the answer myself, haha, I'm so smart, i added this code to the view controller from the story board and it works like a charm.
import UIKit
class ViewController: UIViewController, communicationControllerM {
#IBOutlet weak var Btn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
Btn.addTarget(self, action: #selector(callMenuModal), forControlEvents: .TouchUpInside)
}
func callMenuModal() {
let mainVC = MainViewController()
mainVC.delegate = self
mainVC.modalPresentationStyle = .OverCurrentContext
presentViewController(mainVC, animated: false, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func backFromM() {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
in my xib view controller i added a return action
playBtn.addTarget(self, action: #selector(goBackToMainVC), forControlEvents: .TouchUpInside)
self.delegate?.backFromM()
Thanks guys!!
You load a view controller and its associated nib file exactly the way you are already doing it in your code:
let mainViewController = MainViewController(nibName: "MainViewController", bundle: nil)
That instantiates the view controller, and when you present or push to it, the view will be loaded from the nib and will be placed into the interface.
As a class variable assign this:
var nibName: NibViewClass?
Assign it to the corresponding class made for the nib.
Inside the view controller wherever you want to load the nib, call
nibName = NSBundle.mainBundle().loadNibNamed("NibView", owner: self, options: nil) as? NibViewClass
Make sure that the "NibView" == the name of the Nib UI file. Then you need to add it as a subview like so:
if nibName != nil {
self.view.addsubview(nibName!)
//add this line to make it appear where you want it.
nibName.frame = CGRectMake(xPosition, yPositionOffScreen, nibWidth, nibHeight)
}
Now this will do most of the work for you, but I would recommend animating it as well. There are a few different ways to do so, but one I often use is like so:
UIView.animateWithDuration(0.7, delay: 1.0, options: .CurveEaseIn, animations: {
nibName.frame.origin.y = yPositionOnScreen
}, completion: { finished in
//code to run after nib finishes movement
})
At any point after you assign the nibName to it's corresponding class, you can assign its local variables from inside your viewController. You could also choose to animate the nib in with x positions if preferred. I would use the same function with the y values reversed to send it back offscreen when done with it.

SWIFT 2.2 Warning: Attempt to present TabBar Controller on SignInViewController whose view is not in the window hierarchy

I have a SignInVC, a button to transition to a TabbarVC not segue for the purpose of using a custom transitioning. Although it runs fine, an error pops up when i press the signIn button in the Debug Area.
In the SignInVC
#IBAction func onTapButton(sender: AnyObject) {
btnFromNib.animate(1, completion: { () -> () in
let myTabbarController = self.storyboard?.instantiateViewControllerWithIdentifier("myTabbarController") as! UITabBarController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window?.rootViewController = myTabbarController
myTabbarController.transitioningDelegate = self
self.presentViewController(myTabbarController, animated: true, completion: nil)
})
}
What am i doing wrong? ...
Thanks in advance
Since,you are changing your rootViewController you dont need to present it..So remove this line
self.presentViewController(myTabbarController, animated: true, completion: nil)

Open in same view controller as closed on (swift)

I am making a simple fact app (In swift) and all the facts are in separate view controllers and when the user closes the app, it all goes to the main page and you have to start from fact 1 again.
I want to know how to save what view controller the user was on when they closed it and when they continue through the facts again,it starts on that fact. Thanks:) also if someone makes a video i think it will get enough views to start a YT channel
You can use NSUserDefaults which will remember your last ViewController.
first of all you have to store some integer when you load any view like shown below:
FirstView.swift
override func viewDidLoad() {
super.viewDidLoad()
NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "View")
// Do any additional setup after loading the view, typically from a nib.
}
SecondViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
NSUserDefaults.standardUserDefaults().setInteger(1, forKey: "View")
// Do any additional setup after loading the view.
}
Now In your AppDelegate.swift read that stored values and load the ViewController related to that Integer this way:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let viewCount = NSUserDefaults.standardUserDefaults().integerForKey("View")
var VC = UIViewController()
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
println(viewCount)
if viewCount == 0 {
//FirstView should initiate
VC = storyboard.instantiateViewControllerWithIdentifier("First") as! ViewController
} else if viewCount == 1 {
//SecondView should inititate
VC = storyboard.instantiateViewControllerWithIdentifier("Second") as! SecondViewController
} else {
//ThirdView Should Initiate
VC = storyboard.instantiateViewControllerWithIdentifier("Third") as! ThirdViewController
}
self.window?.makeKeyAndVisible()
self.window?.rootViewController = VC
return true
}
Check out THIS sample project for more Info.

Resources