Cocoa swift load ViewController and and storyboard view from AppDelegate - swift

I have created a SideBar() class which creates a NSView with various buttons.
I instantiate my sideBar() in my AppDelegate by doing
func applicationDidFinishLaunching(_ notification: Notification) {
sideBarView.setupSideBarView()
sideBarView.menuButton.action = #selector(self.NewMenuButton(_:))
}
#objc func NewMenuButton(_ sender: NSButton) {
}
In my Initial ViewController I then present my sideBar in the following way:
view.addSubview(sideBarView.getView())
With the press of menuButton I would like the function in the App Delegate to load and present a new storyboard view with its ViewController.
Can this be done?
Thanks.

I solved the issue giving my second ViewController a storyboard id.
Then, through the AppDelegate function:
let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: Bundle.main)
let mainPageController = storyboard.instantiateController(withIdentifier: "test") as! SecondViewController
NSApplication.shared.mainWindow?.contentViewController = mainPageController

Related

Navigate from a controller to another controller having a root controller between them

I have 3 controllers: RootController, FirstController and SecondController.
I want to navigate from RootController -> FirstController (here I press a button) -> Take me to SecondController.
How can I do this without Notifications and Observers and without to create a segue from that button to SecondVC because after I need to press < Back and again < Back.
This is what I've tried to do but is not working:
import UIKit
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func goToSecondVC(_ sender: UIButton) {
// Go from first VC to second VC
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let showSecondVC = storyBoard.instantiateViewController(withIdentifier: "goSecondVC") as! SecondViewController
self.present(showSecondVC, animated:true, completion:nil)
}
}
For your code example to work your SecondViewController needs to have the Storyboard ID set to "goSecondVC". This is done in the Identity inspector in the third tab in the right pane. This will present your ViewController modally. However since you have a navigationController you most likely want to push the SecondViewController on the navigationStack like so:
navigationController?.pushViewController(secondVC, animated: true)

Swift: "Use of undeclared type" when trying to push to existing view controller

so I'm trying to push to existing view controller on the storyboard programmatically ,but I'm getting Use of undeclared type: LoginViewController even that I set the Storyboard ID to LoginViewController here is my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myButton: UIButton!
#IBAction func Button(_ sender: UIButton) {
if let ButtonImage = myButton.image(for: .normal),
let Image = UIImage(named: "ButtonAppuyer.png"),
UIImagePNGRepresentation(ButtonImage) == UIImagePNGRepresentation(Image)
{
let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.navigationController?.pushViewController(loginVC, animated: true)
} else {
print("OK")
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thank you in advance!
Make sure you create a new class LoginViewController that inherits from UIViewController.
To do so go to the File menu > New > File
In the iOS tab, choose Cocoa Touch Class
And then Next
Give the class name LoginViewController, and make it a subclass of UIViewController
Click Next and then Create. That will add a new file to your project, and you could/should customize its contents later.
In your storyboard, in the Identity Inspector tab, make sure to set the class name and the identifier to LoginViewController.

Storyboard initialization and deinit

When initializing a ViewController via a Storyboard (NS or UI), do you need to keep a reference to the storyboard or can you just ignore it when you are done with it and let it deinit?
class ViewController: NSViewController {
var secondarySB: NSStoryboard? = nil
#IBAction
func loadAndKeep(_ sender: NSButton) {
//keeping a reference
secondarySB = NSStoryboard.init(name: NSStoryboard.Name.init(rawValue: "Secondary"), bundle: nil)
let vc = secondarySB?.instantiateInitialController() as! Secondary
self.view.addSubview(vc.view)
}
#IBAction
func load(_ sender: NSButton) {
//ignoring the storyboard after I get the viewcontroller
let sb = NSStoryboard.init(name: NSStoryboard.Name.init(rawValue: "Secondary"), bundle: nil)
let vc = sb.instantiateInitialController() as! Secondary
self.view.addSubview(vc.view)
}
}
You do not need to keep a reference to the storyboard, but you do need to add the instantiated view controller as a child view controller.

Push navigation from xib Files to storyboard viewcontroller in swift3 [duplicate]

I have a view in my xib file which contain buttons. i want to move to a ViewController when i will press the button (#IBAction). I have used below code
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("About") as! AboutViewController
self.presentViewController(nextViewController, animated: true, completion: nil)
I am getting the error "Value of type 'SlideMenuView' has no member 'presentViewController'.
because my class is a UIView type :
class SlideMenuView: UIView {
}
so how can I navigate to other view controller.
That is beacuase the class you are trying to present from is a UIView and not a UIViewController. It has no Present method.
I'm guessing your view (SlideMenuView) is embedded inside a viewcontroller. what you need to do is implement a delegate, and inform your containing viewController to present next Viewcontroller.
code below:
#protocol SlideMenuViewDelegate: class {
func slideMenuViewAboutButtonClicked(menuView: SlideMenuView)
class SlideMenuView: UIView {
weak var delegate: SlideMenuViewDelegate?
#IBAction func aboutButtonClicked(sender: AnyObject) {
self.delegate?.slideMenuViewAboutButtonClicked(self)
}
now, in your viewController, implement this delegate method:
func slideMenuViewAboutButtonClicked(menuView: SlideMenuView) {
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("About") as! AboutViewController
self.presentViewController(nextViewController, animated: true, completion: nil)
}
Also, dont forget to assign the sliderMenuView object the viewcontroller as a delegate.
something like:
self.sliderMenuView.delegate = self // (self == the containing viewController
I did it in a different way. In class file
class SlideMenuView: UIView {
var navigationController: UINavigationController? // Declare a navigation controller variable
// And create a method which take a navigation controller
func prepareScreen(navController: UINavigationController)-> UIView {
navigationController = navController
let nibView = NSBundle.mainBundle().loadNibNamed("SlideMenuView", owner: self, options: nil)[0] as! UIView
self.addSubview(nibView)
return nibView
}
// In Button action
#IBAction func btnAction(sender: UIButton) {
var storyBoard = UIStoryboard(name: "Main", bundle: nil)
let nextViewController = storyBoard!.instantiateViewControllerWithIdentifier("NextViewController") as! UIViewController
navigationController?.pushViewController(nextViewController, animated: true)
}
}
// For calling from UIViewController
slideBarMenuIstance.prepareScreen(self.navigationController!)

ios swift method to navigate through viewcontroller programatically

i would like create my function to navigate through my views.
i have a function
func ShowView(name:String,caller:AppDelegate){
//story board
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initViewController: UIViewController = storyBoard.instantiateViewControllerWithIdentifier(name) as UIViewController
caller.UIWindow?.rootViewController = initViewController
}
but i need to call this function from AppDelegate and UIViewController , how can i get uiwindow from UIViewController , from AppDelegate is ok but i can't keep AppDelegate like caller parameter cause i would like that it work with UIViewController.
I don't really know which i must use for my parameter.
many thanks
You don't need to replace rootView Controller every time if you are moving from master to details views. Connect root view to details view using segue. Set a identifier to segue in your storyboard. Overide prepareForSegue in your viewController class.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "showDetails")
{
var viewController=segue.destinationViewController as DetailsView
//set data
}
}