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
...
}
Related
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
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)
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()
}
My app rootviewcontroller is with tab bar, but when I use firebase push notification it only allows me "present" method. I want to view the controller with push (like child) to have the tab bar and back option when i view this view controller.
In my code I want to transfer from present to PUSH but i cant find solution. currentController.present(controller, animated: true, completion: nil)
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
if Defaults.hasKey(.logged), let logged = Defaults[.logged], logged == true {
//TODO
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProductDetailsViewController") as? ProductDetailsViewController {
controller.productFromNotificationByCode(code: userInfo["product_code"] as! String, productID: userInfo["product_id"] as! String)
if let window = self.window, let rootViewController = window.rootViewController {
var currentController = rootViewController
while let presentedController = currentController.presentedViewController {
currentController = presentedController
}
currentController.present(controller, animated: true, completion: nil)
}
}
}
print(userInfo)
}
completionHandler()
}
The easiest way to do it would be to wrap your root view controller in a UINavigationController in your storyboard. This would make the actual root controller a UINavigationController rather than a UITabBarController.
once that is done you can simply do
if let window = self.window, let rootNavController = window.rootViewController as? UINavigationController {
navigationController?.pushViewController(controller, animated: true)
}
Alternately, if all you're really looking for is a "Slide from the right" animation and don't need a full navigation stack, you could write a custom view controller transition that gave a similar effect using modal controllers.
I have not tested yet, but I believe it's just works. Try this:
func pushViewController() {
let storyboard = UIStoryboard.init(name: "YourStoryboardName", bundle: nil)
let tabBarController = storyboard.instantiateViewController(withIdentifier: "YourTabBarController") as! UITabBarController
let navigationController = storyboard.instantiateViewController(withIdentifier: "YourNavigationController") as! UINavigationController
let productDetailsViewController = storyboard.instantiateViewController(withIdentifier: "ProductDetailsViewController") as! ProductDetailsViewController
tabBarController.viewControllers = [navigationController]
if tabBarController.selectedViewController == navigationController {
navigationController.pushViewController(productDetailsViewController, animated: true)
}
self.window = UIWindow.init(frame: UIScreen.main.bounds)
self.window?.rootViewController = tabBarController
self.window?.makeKeyAndVisible()
}
override init() {
super.init()
parseLoginHelper = ParseLoginHelper {[unowned self] user, error in
// Initialize the ParseLoginHelper with a callback
if let error = error {
// 1
ErrorHandling.defaultErrorHandler(error)
} else if let _ = user {
// if login was successful, display the TabBarController
// 2
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let tabBarController = storyboard.instantiateViewControllerWithIdentifier("TabBarController")
// 3
self.window?.rootViewController!.presentViewController(tabBarController, animated:true, completion:nil)
}
}
}
So I understand that the code here should be able to replace my login screen upon hitting login, however, it does not. Instead it loads and stays on the login screen for parse. However, if I exit the app, it loads the proper screen. Does anyone have any ideas how to dismiss login screen more efficiently upon login?
let user = PFUser.currentUser()
let startViewController: UIViewController;
if (user != nil) {
// 3
// if we have a user, set the TabBarController to be the initial view controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
startViewController = storyboard.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController
} else {
// 4
// Otherwise set the LoginViewController to be the first
let loginViewController = PFLogInViewController()
loginViewController.fields = [.UsernameAndPassword, .LogInButton, .SignUpButton, .PasswordForgotten]
loginViewController.delegate = parseLoginHelper
//loginViewController.signUpController?.delegate = parseLoginHCelper
startViewController = loginViewController
}
// 5
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = startViewController;
self.window?.makeKeyAndVisible()
return false
}
I believe you should not call
self.window?.rootViewController!.presentViewController(tabBarController, animated:true, completion:nil)
instead if you already in some controller why just go to tabBar like that:
presentViewController(tabBarController, animated:true, completion:nil)
You should not use :
self.window?.rootViewController!.presentViewController(tabBarController, animated:true, completion:nil)
Try to change that line by :
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("tabBarController") as! tabBarController
self.presentViewController(vc, animated: true, completion: nil)
and in your storyboard, set the storyboard id of tabBarController under identity inspector to : tabBarController