Presenting ViewController Dynamically - ios

i am presenting a ViewController like this
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let ViewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.present(ViewController, animated: true, completion: nil)
is there any way to pass storyboard name,identifier, and View Controller type dynamically

Create New File StoryBoard.swift
let mainBundle = Bundle.main
enum Storyboard: String {
case main = "Main"
case TeamLeader = "TeamLeader"
case Installer = "Installer"
}
extension Storyboard {
var instance: UIViewController {
return UIStoryboard(name: Storyboard.main.rawValue, bundle: mainBundle).instantiateViewController(withIdentifier: self.rawValue)
}
}
Create New ControllerIdentifier.swift File
enum ControllerIdentifier: String {
case CustomerDetailsVC
case TeamVC
case MyProfileVC
case CancelOrderVcViewController
case ApprovingCustomerVC
case RequestsDetailVC
case NewrequestTL
case ApprovedTLVC
case HistoryTLVC
case SettingsTeamleaderVC
case HistoryDetailVC
case ApprovingCustomerFirstVC
case ApprovingCustomerSecondVC
case ApprovingCustomerForthVC
case ApprovingCustomerFifthVC
case tabbar2
case ApprovingCustomerThridVC
case SignatureVC
case NewRequestsVC
case tabbar
case LoginVC
case CustomerDetailsTL
case InstallationApprovingFirstVC
case InstallationApprovingSecondVC
case InstallerDashBoardVC
case tabbar3
case HistoryInstallerVC
case OrderInProgressVC
case SettingsInstallerVc
case RequestDetailInstallerVC
case HistoryDetailsInstallerVC
case LocationInstallerVC
case CancelOrderInstallerVC
case MyProfileInstallerVC
}
extension UIViewController{
func pushToController(from name : Storyboard, identifier: ControllerIdentifier) {
DispatchQueue.main.async { [self] in
let storyboard = UIStoryboard(name: name.rawValue, bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: identifier.rawValue)
navigationController?.pushViewController(vc,animated: true)
}
}
func pushToRoot(from name : Storyboard, identifier: ControllerIdentifier) {
DispatchQueue.main.async { [self] in
let storyboard = UIStoryboard(name: name.rawValue, bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: identifier.rawValue)
let navigationController = UINavigationController(rootViewController: vc)
navigationController.modalPresentationStyle = .fullScreen
self.present(navigationController, animated: true, completion: nil)
}
}
func imageScreenPush(from name : Storyboard, identifier: ControllerIdentifier) {
DispatchQueue.main.async { [self] in
let storyboard = UIStoryboard(name: name.rawValue, bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: identifier.rawValue)
let navigationController = UINavigationController(rootViewController: vc)
navigationController.modalPresentationStyle = .overCurrentContext
self.present(navigationController, animated: true, completion: nil)
}
}
}
How To Use
self.pushToController(from: .Installer, identifier: .tabbar3)
Make sure StoryBoard Name and UIViewController Identifier should be same in Enum cases

Related

how to passdata between storyboard

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator){
if UIDevice.current.orientation.isPortrait{
let secondView: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let main = secondView.instantiateViewController(withIdentifier: "ViewController") as! ViewController
main.modalPresentationStyle = .fullScreen
self.present(main, animated: true, completion: nil)
}
if UIDevice.current.orientation.isLandscape{
self.dismiss(animated: true, completion: nil)
}
}
I use this code to switch between two different storyboard's viewcontroller. How can I pass data between those viewcontroller in two different storyboard.
I have tried "main.instanceData = myData before the present" It seems could work, but the initial value of myData is nil, so when this line of code was executed, it would show "Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value"
Just try this. You can pass data to viewController directively like that:
let secondView: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let main = secondView.instantiateViewController(withIdentifier: "ViewController") as! ViewController
main.data = yourdata
main.modalPresentationStyle = .fullScreen
self.present(main, animated: true, completion: nil)

how to present and dismiss at same time

This is my Code
#IBAction func backButton(_ sender: UIButton) {
self.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
self.present(vc, animated: true, completion: nil)
})
}
this is not working only dissmising
I dont't understand your questions well. I think you want to present a new ViewController. You can use this:
UIView.animate{duration: 0.5, animations: {
(UIApplication.shared.delegate as! AppDelegate).window!.rootViewController = NextViewController()
}}
Problem is that you are dismissing self and then trying to present a new view controller on that exact same self - but at that moment self is already dismissed. You need to present that new view controller from the parent of the current view controller. I believe the best way is to setup a delegate. So the controller that you showed us and that you want to dismiss will have this:
protocol FirstDelegate: class {
func firstDismiss(_ first: First)
}
class First: UIViewController {
weak var delegate: FirstDelegate?
#IBAction func backButton(_ sender: UIButton) {
// this will tell the delegate to dismiss this contorller and present the other one
delegate?.firstDismiss(self)
}
// rest of the code omitted
}
Next, you will have to setup this in the parent that presents First view controller (here I assume that presentFirst method presents the First view controller):
class ParentViewController: UIViewController, FirstDelegate {
// rest of the code
func presentFirst() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let firstVC = storyboard.instantiateViewController(withIdentifier: "First") as! RequestItemPackageDetails
// set delegate to first:
firstVC.delegate = self
self.present(firstVC, animated: true, completion: nil)
}
func firstDismiss(_ first: First) {
first.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
self.present(vc, animated: true, completion: nil)
})
}
}
Not quite sure with your Qns, but try this one out.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
vc.previousVC = self
self.present(vc, animated: true)
RequestItemPackageDetails.swift
var previousVC : UIViewController!
override viewDidLoad() {
previousVC.dismiss(animated: false, completion: nil)
}
You can dismiss self and then present another view from rootViewController
self.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window!.rootViewController?.present(vc, animated: true, completion: nil)
})

Unable to Instantiate View Controller

I have a function, whereby I check if the UserDefaults are set and if not a new View Controller opens and presents a login screen which will set the user defaults.
My problem is the view controller does not Instantiate but I get a print "User not registered"
func checkUserAccount() {
let defaults = UserDefaults.standard
let accountName = defaults.bool(forKey: "PUserAccountName")
let accountPassword = defaults.bool(forKey: "PUserAccountPassword")
if accountName == true && accountPassword == true {
print("User Registered")
} else {
let storyboard: UIStoryboard = UIStoryboard(name: "PolTRiM", bundle: nil)
let vc: StudentLoginVC = storyboard.instantiateViewController(withIdentifier: "studentLogin") as! StudentLoginVC
vc.modalPresentationStyle = .custom
vc.modalTransitionStyle = .crossDissolve
self.present(vc, animated: true, completion: { _ in })
print("User not registered")
}
}
Any thoughts?
Have you double checked UIStoryBoard name and UIViewController identifier if it's written correctly? Otherwise this code is working for me
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"MyViewController") as! UIViewController
self.present(viewController, animated: true)

Moving to another storyboard inside closure

api.postUserLogin(Parameters: params) { (json) in
print(json)
if (json["status"].string == "true") {
self.user.id = json["data"]["id"].string
self.user.verify_status = json["data"]["verify_status"].string
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainViewController") as UIViewController
present(vc, animated: true, completion: nil)
}
}
Try this code:
func callViewController(){
let viewController: UIViewController = UIStoryboard(name:"STORYBOARD_NAME",bundle:nil).instantiateViewController(withIdentifier: "MainViewController")
let window :UIWindow = UIApplication.shared.keyWindow!
window.rootViewController = viewController
window.makeKeyAndVisible()
}

3D touch to UITabView

I am using a tabViewController and want to know how I can make a 3D touch action from the home screen bring up a tab. I already have the code but can't seem to get a specific tab to show up; I can only get a window. My AppDelagate.swift is below. Any help?
enum ShortcutIdentifier: String
{
case First
case Second
init?(fullType: String)
{
guard let last = fullType.componentsSeparatedByString(".").last else {return nil}
self.init(rawValue: last)
}
var type: String
{
return NSBundle.mainBundle().bundleIdentifier! + ".\(self.rawValue)"
}
}
func handleShortcutItem(shortcutItem: UIApplicationShortcutItem) -> Bool
{
var handled = false
guard ShortcutIdentifier(fullType: shortcutItem.type) != nil else {return false}
guard let shortcutType = shortcutItem.type as String? else {return false}
switch (shortcutType)
{
case ShortcutIdentifier.First.type:
handled = true
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navVC = storyboard.instantiateViewControllerWithIdentifier("sourcesview") as! UINavigationController
if let tabBarController = navVC.topViewController as? UITabBarController {
tabBarController.selectedIndex = 4
}
self.window?.rootViewController?.presentViewController(navVC, animated: true, completion: nil)
break
case ShortcutIdentifier.Second.type:
handled = true
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navVC = storyboard.instantiateViewControllerWithIdentifier("searchview") as! UINavigationController
self.window?.rootViewController?.presentViewController(navVC, animated: true, completion: nil)
break
default:
break
}
return handled
}
You have to set the selectedTab property on your UITabBarController. I assume that the UINavigationController that you load from the nib contains a UITabBarController as top view controller, so after loading the navigation controller from the nib you have to access the tab bar controller and set the selected tab property to the desired tab.
switch (shortcutType)
{
case ShortcutIdentifier.First.type:
handled = true
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navVC = storyboard.instantiateViewControllerWithIdentifier("sourcesview") as! UINavigationController
if let tabBarController = navVC.topViewController as? UITabBarController {
tabBarController.selectedIndex = 1
}
self.window?.rootViewController?.presentViewController(navVC, animated: true, completion: nil)
break
...
}

Resources