storyboard! vs. UIStoryboard(name: "Main", bundle: nil) - ios

I got put into a project that has the following declaration:
UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("asdf") as! AsdfViewController
I've always used storyboard! to do this. It is my understanding that storyboard! will always give me UIStoryboard(name: "Main", bundle: nil). Is this a dangerous assumption to make?
I know that you may want to use the official constructor for UIStoryboard if you wanted to reference a different storyboard file, but is it safe to abbreviate it to storyboard! if you are sure that the VC you wish to instantiate is part of Main.storyboard?

If you are calling self.storyboard from a view controller that is on another storyboard file, it will give reference to that particular storyboard; not the main storyboard. By mentioning:
UIStoryboard(name: "Main", bundle: nil)
You can make sure that you are referencing the main storyboard always.
In following situations:
Have only one storyboard file
Instantiate a view controller which is also included in the current view controller's storyboard
using self.storyboard is enough.

Related

Instantiate view controller created in storyboard from a storyboard less view controller

I have two View Controllers:
MainController.swift - Soryboard less view controller
SecondController.swift - Storyboard view controller
How can I instantiate SecondController in MainController?
storyboard?.instantiateViewController(withIdentifier: _) does not work because MainController has no storyboard.
How can I open SecondController in MainController?
It depends what “open” means. You can, for example, say
present(SecondController(), animated:true)
Or you might push it onto a navigation controller if there is one in the interface. That sort of thing, and similar, are quite standard. Storyboards are a relatively recent innovation; when I started programming iOS everything was done without them.
Use init(name:bundle:):
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondVC = storyboard.instantiateViewController(withIdentifier: "SecondController") as! SecondController
If you want to see example usage in an app then take a look at this file.

Problems using self.navigationController?.pushViewController(newViewController, animated: true)

the thing is im new to ios development this is my second application while working on the first one i mainly used a theme and then worked over it but this one im working from scratch.
My main problem is going from one screen to another
When i use this code it works
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "servicesScreen") as! ServiceViewController
nextViewController.modalPresentationStyle = .fullScreen
self.present(nextViewController, animated:true, completion:nil)
But i need to use this one so i can go back too but this wont do anything
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "servicesScreen") as! ServiceViewController
self.navigationController?.pushViewController(newViewController, animated: true)
My question is, am i doing anything wrong here or do i need to add something in scenedeligate?
try
select Main.storyboard
select initial view Controller
select editor -> Embed in -> navigation controller.
For this, you need to add navigation controller to initial storyboards.
If you are using navigationController you need to add a navigation controller first on storyboard or programmatically.
Programmatically add navigation controller check this link:-
Creating a navigationController programmatically (Swift)
or
To add navigation controller on storyboard you should follow this link:-
https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/ImplementNavigation.html
If you have added navigation controller to your app then make sure your intialViewController is set to navigation controller or your navigation controller is added to the stack when you run your application.
Also check for "Is the identifier correct? Did you reference the correct storyboard?".

Load view controller to container view smaller than screen size

I have a container view used for navigation.
It's height is 75% of screen height, and on my main navigation controller I load this container, and to this container I load another controller :
let storyboard = UIStoryboard(name: "Main", bundle: nil)
controller1 = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
controller1.delegate=self
controller1.view.frame=ContainerView.bounds
ContainerView.addSubview(controller1.view)
addChildViewController(controller1)
controller1.didMove(toParentViewController: self)
What happens is that this controller covers all screen, not just 75% of it, and behind it I see the other container- used as bottom bar, but it should not cover it.
Story board:
On reality, "container", covers the "bar".
A sample project created using two container Views
Two Container Views and Two Different VC to be added in Those Views
Link - https://github.com/iOS-Geek/ContainerViews.git
StoryBoard :
Expected Output :-
Can use as Many Container Views And Subviews Try checking once
Updated Answer As in your code
let storyboard = UIStoryboard(name: "Main", bundle: nil)
controller1 = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
controller1.delegate=self
controller1.view.frame=ContainerView.bounds
ContainerView.addSubview(controller1.view)
addChildViewController(controller1)
controller1.didMove(toParentViewController: self)
Everything is fine but here need to add one more property that will Hopefully solve your problem of getting subview out of bounds
need to set translatesAutoresizingMaskIntoConstraints to true
So Try using code as
let storyboard = UIStoryboard(name: "Main", bundle: nil)
controller1 = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
controller1.delegate=self
controller1.view.frame=ContainerView.bounds
ContainerView.addSubview(controller1.view)
addChildViewController(controller1)
controller1.view.translatesAutoresizingMaskIntoConstraints = true
controller1.didMove(toParentViewController: self)

instantiateInitialViewController(withIdentifier: String) does not exist?

Here is a screenshot from Xcode 8.2:
If the function does not exist, how do you add identifier to a view controller these days?
Use instead instantiateViewController(withIdentifier:) when you would like a ViewController and attach a view from the storyboard (UIStoryboard Id Identifier)
instantiateInitialViewController() is to instantiate the default view initial, this function takes no argument and is something you wouldn't usually do programmatically.
let sb = UIStoryboard(name: "", bundle: Bundle.main)
sb.instantiateViewController(withIdentifier: "blue")

(lldb) po self.storyboard nil

How/when can a UIViewController return self.storyboard nil.
I am trying to instantiate a ViewController with:
self.storyboard!.instantiateViewControllerWithIdentifier
But self.storyboard is nil?
Note: the plist is set to the right storyboard.
Per the Apple documentation, UIViewController's storyboard property represents the storyboard from which the view controller originated. It returns an optional UIStoryboard instance which is nil if the view controller was not instantiated from a storyboard.
Try this :
let localStoryboard = UIStoryboard(name: "Main", bundle: nil)

Resources