I have 3(cv1, cv2, cv3) container views place on same position on mainViewContoller.
All 3 having different viewController classes (.swift)
Button is placed on cv2(secondViewController), on that button click I want to change containerView from cv2 to cv3.
For more clear, how can I call mainViewController method from secondViewController (cv2)?
secondViewController.swift
#IBAction func nextButtonClick(sender: UIButton) {
// Want to call action of firstViewController which is changeContainerView()
}
firstViewController.swift
funct changeContainerView(){
loginContainerView.hidden = true
signUpContainerView.hidden = false
}
Like that.
You should use the delegate pattern. It's very common in the Cocoa framework. See the documentation if you don't know how it works.
Try this
dispatch_sync(dispatch_get_main_queue(), { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let svc = storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
self.presentViewController(svc, animated: true, completion: nil)
})
Yout need just change mainstoryboard name if it needed and name of destination VC in 2 places
Related
im on my first app with swift right now. and I want to make 2 Pages.
1.Page -> Button -> 2.Page
it works but the 2.Page looks not like fullscreen ?! more like a Page to slide?
i wann a normal 2.Page like the first one. hope you know what I mean :D thank you for your help.
enter image description here
enter image description here
You just have to go to story board select the 2nd view controller and change presentation style to "Full Screen". Please refer this
If your SecondViewController is created in programmatic code without the storyboard the following code will work without problem
Solution1:
class FirstController: UIViewController {
func presentSecondController() {
// create instance of secondVC
let secondController = UIViewController(nibName: nil, bundle: nil)
// Change presentation style
secondController.modalPresentationStyle = .fullScreen
// Present secondVC
self.present(secondController, animated: true, completion: nil)
}
}
`
Solution2:
2.a If SecondViewController is created in the storyboard, you will have to add a StoryboardID to your SecondViewController like the following image:
2.b instantiates secondController instance from the storyboard by adding this code:
class FirstController: UIViewController {
func presentSecondController() {
// Create storyboard instance from name file
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Instantiate secondVC from storyboardID
guard let secondController = storyboard.instantiateViewController(withIdentifier: "secondControllerID") as? SecondController else { return }
// Change presentation style
secondController.modalPresentationStyle = .fullScreen
// Present secondVC
self.present(secondController, animated: true, completion: nil)
}
}
Presenting ViewController Using storyBoard:
if newViewController is in StoryBoard.we can present it using the following method.
let storyboard = UIStoryboard(name: "AViewController"), bundle: UIBundle.main)
let newViewcontroller = storyboard.instantiateInitialViewController() as? AViewController
self.present(newViewcontroller, animated: false, completion: nil)
Is it Possible to present a ViewController which is not in storyBoard but its parent viewcontroller has storyboard
I have create a B viewcontroller programatically (No StoryBoard) ,now I would like to present BViewController and it should use the AViewController StoryBoard?
class AViewController : UIViewController
{
//this class is in storyboard which is generic design that I want to use it in different ways.
}
class BViewController : AViewController
{
....//
}
e.g.
self.present(BViewController(), animated: false, completion: nil)?
when I present BViewcontroller it throws nil for parameters which are from super class.
I founded the answer to reuse the story board file or inherite the story board file.
object_setClass(Sets the class of an object.) will override instance of AViewController with BViewController Class. So on top of AViewController you can add some more methods.
when you have similar viewcontroller with small changes. you have to create different viewcontrollers. using this method you can create on basic viewcontroller with storyboard and reuse that viewcontroller .
class BViewController{
static func vcInstanceFromStoryboard() ->BViewController? {
let storyboard = UIStoryboard(name: "AViewController"), bundle: UIBundle.main)
let instance = storyboard.instantiateInitialViewController() as? AViewController
object_setClass(instance, BViewController.self) //
return (instance as? BViewController)!
}
.....
}
This is an example of how do we use it:
let vc = BViewController.vcInstanceFromStoryboard()
self.present(vc , animation : true)
Your code will work fine if your ViewController truly isn't in a Storyboard. All you have to do is instantiate it without a nibName, like this:
class ViewController: UIViewController {
init() {
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
Normal Storyboard ViewControllers rely on the coder init to be created, but you can create them normally with the nibName: nil initializer, as long as you don't have any outlets on it (which is your case since the ViewController is not on a storyboard)
Everything is possible programmatically. Not everything is possible through Interface Builder. Storyboards are just a component of Interface Builder.
To present a view controller programmatically from the root:
#objc private func presentViewController() {
guard let root = UIApplication.shared.keyWindow!.rootViewController else {
return
}
let destination = SomeViewController()
destination.transitioningDelegate = YourAnimationVendor()
destination.modalPresentationStyle = .custom
root.present(destination, animated: true, completion: nil)
}
You can omit the transitioning delegate (and the custom animation vendor) and present using a stock UIKit animation, like .fullScreen instead of .custom.
#objc private func presentViewController() {
guard let root = UIApplication.shared.keyWindow!.rootViewController else {
return
}
let destination = SomeViewController()
destination.modalPresentationStyle = .fullScreen
root.present(destination, animated: true, completion: nil)
}
Our App should be able to go from the main storyboard to another storyboard which contains a splitViewController that leads to a searchbar.
We created the searchbar in another storyboard and connected it to the navigation controller like this:
#IBAction func artikelButton(_ sender: Any) {
let viewController = self.storyboard!.instantiateViewController(withIdentifier:"MasterViewController")
self.navigationController?.pushViewController(viewController, animated: true)
}
If you then press that button the app crashes with the SIGABRT error.
The other 2 Buttons work fine, the difference is that they are .xib files.
Here's how we made the .xib buttons:
#IBAction func infoButton(_ sender: Any) {
let vc = InfoViewController(
nibName: "InfoViewController",bundle: nil)
navigationController?.pushViewController(vc, animated: true)
}
If you load your viewcontroller from XIB. then self.storyboard will always nil.
if you are using multiple storyboard or multiple XIB's A better solution
have abstract method practice in your every viewcontroller to access from storyboard
Just like add following (change viewcontroller name and identifier as per yours )
// MARK: - Abstract Methods
public class func viewController () -> LoginVC {
return StoryBoard.main.instantiateViewController(withIdentifier: StoryBoard.controller.LoginVC) as! LoginVC
}
// Now access it with LoginVC.viewController() and do push or present whatever your operation you requred
I manage everything in constant file
public struct StoryBoard {
static let main = UIStoryboard.init(name: "Main", bundle: nil)
struct controller {
static let LoginVC = "LoginView"
}
}
I have a viewcontroller that presents from a .xib.
Inside the .xib there is a button; I want the button to pushviewcontroller to an other viewcontroller (ViewControllerPeopleNew).
I use an action button:
#IBAction func _hitPeople(sender: AnyObject) {
let mapViewControllerObejct = self.storyboard?.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
But got an error:
Signal SIGABRT
unrecognized selector sent to instance
I already checked all about name identifier viewcontroller and all is right.
From view controller present with XIB you can not get storyboad use below code
#IBAction func _hitPeople(sender: AnyObject) {
let storyboard = UIStoryboard(name: "storyboadname", bundle: nil)
let mapViewControllerObejct = storyboard.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
Always remember that you can only use self.storyBoard to instantiate a view controller when both the view controllers (To and From view controllers) belong to the same storyboard. If not then you need to first get a reference to the storyboard your To view controller belongs to. So you need to do this:
#IBAction func _hitPeople(sender: AnyObject) {
let stotyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let mapViewControllerObejct = storyboard?.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
PS: Just be sure that your From view controller is in the navigation stack i.e. self.navigationController is not nil.
I have the following ViewController structure, see image below.
Whenever I want to move from ViewController 1 to any of the other main controllers I use self.tabBarController?.selectedIndex = indexNumber
// for instance, this would take me to ViewController 3
self.tabBarController?.selectedIndex = 2
Based on the picture below, how can I go from ViewController 1 to TargetViewController programmatically when a button is tapped in ViewController 1?
FYI -
In the picture below I'm showing a button in ViewController 3 this is just to show the storyboard structure, the actual button-tap will happen in ViewController 1
EDIT:
Here is how you do it based on Prashant Tukadiya's answer.
ViewController 1
In ViewController 1 add the following in your tap event.
self.tabBarController?.selectedIndex = 2
let nav = (self.tabBarController?.viewControllers?[2] as? UINavigationController)
let vc = TargetViewController.viewController()
nav?.pushViewController(vc, animated: true)
TargetViewController
In your TargetViewController add the following class method.
class func viewController() -> TargetViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
return storyboard.instantiateViewController(withIdentifier: "targetViewControllerID") as! TargetViewController
}
Add targetViewControllerID in the Storyboard ID field.
I was facing same before a couple of days and finally, I got a solution maybe this will help you.
TabController.shared.tabcontroller.selectedIndex = 1
let navigation = TabController.shared.tabcontroller.selectedViewController?.navigationController
let SavedAddress = self.storyboard?.instantiateViewController(withIdentifier: "SavedAddressVC") as! SavedAddressVC
navigation?.pushViewController(SavedAddress, animated: true)
I have used the same solution. and this is the working code for me.
You can directly give identifier to the TargetViewController from storyboard and load from storyboard then and push or present it.
like add this method in your TargetViewController
class func viewController () -> TargetViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
return storyboard.instantiateViewController(withIdentifier: "yourIdentifer") as! TargetViewController
}
and on tap event
let vc = TargetViewController.viewController()
self.navigationController?.pushViewController(vc, animated: true)
EDIT
After reading comments got clear idea about your requirements
On button action from ViewController1, You want to goto TargetViewController but when press back you want back to viewController 3
Select particular index first
self.tabBarController?.selectedIndex = 2
After that you need to grab UINavigationController
let nav = (self.tabBarController?.viewControllers?[2] as? UINavigationController)
then Push ViewController
let vc = TargetViewController.viewController()
nav?.pushViewController(vc, animated: true)
Note: Don't forgot add identifier to storyboard to TargetViewController and also add class func viewController () -> TargetViewController method to TargetViewController
Hope it is helpful
In action function of a button in ViewController 1 , you can use this :
func presentMethod(storyBoardName: String, storyBoardID: String) {
let storyBoard: UIStoryboard = UIStoryboard(name: storyBoardName, bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: storyBoardID)
self.definesPresentationContext = true
self.present(newViewController, animated: true, completion: nil)
}
//usage
presentMethod(storyBoardName: "Main", storyBoardID: "TargetViewController")