How can I open a specific Tab View from AppDelegate - swift

My root view is a tab bar controller, I would like to open the app on a specific tab when a certain notification is received. If I use presentViewController the tab bar disappears. Is there a specific way to do this?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let myTabBar = self.window.rootViewController as! UITabBarController // Getting Tab Bar
myTabBar.selectedIndex = 2 //Selecting tab here
return true
}

Related

Back Buttons from navigation bar are overlapping , swift 4

I was trying to customize my back button according to this tutorial.
In AppDelegate,
let barButtonAppearence = UIBarButtonItem.appearance()
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
let backButton = UIImage(named: "back_arrow")
let backButtonImage = backButton?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 10)
barButtonAppearence.setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)
return true
}
And then it is conflicting with the existing one (which appeared automatically because of segue(Show).
So I need to remove the blue one.
There are two things need to accomplish what you are trying to achieve:
Changing the back button's default image to your supplied image
Removing the title from the back button item
To change back button's image:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Remember, this will change every navigation bar's back button image in your app
UINavigationBar.appearance().backIndicatorImage = #imageLiteral(resourceName: "backButton")
UINavigationBar.appearance().backIndicatorTransitionMaskImage = #imageLiteral(resourceName: "backButton")
return true
}
Note: If you don't want that all your navigation bar back button to have the supplied image, you may need to subclass UINavigationController and update its navigation bar.
Removing the title from the back button item:
We will do this by adding a method to any UIViewController through extension. Extension method will be used here so that any UIViewController can be able to have this behavior when it wants.
extension UIViewController {
func removeNavigationBarBackButtonItemTitle() {
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItem.Style.plain, target: nil, action: nil)
}
}
Now, in any push transition for VC A -> VC B you need to hide the back button's title. But you have to invoke the method removeNavigationBarBackButtonItemTitle() from VC A. Just remember this and you are good to go.
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
removeNavigationBarBackButtonItemTitle()
}
}
You will find a demo here. The demo also has some other implementations too. But you will get what you need and what I've said above.
Have you tried replacing it this way:
UINavigationBar.appearance().backIndicatorImage = UIImage(named: "back_arrow")
UINavigationBar.appearance().backIndicatorTransitionMaskImage = UIImage(named: "back_arrow")
I have tried this on applicationDidFinishLaunching method in AppDelegate
Another alternative solution to set tint color clear. See the below-modified code of your.
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
let backButton = UIImage(named: "back_arrow")
let backButtonImage = backButton?.stretchableImage(withLeftCapWidth: 0, topCapHeight: 10)
barButtonAppearence.setBackButtonBackgroundImage(backButtonImage, for: .normal, barMetrics: .default)
barButtonAppearence.tintColor = UIColor.clear
return true
}

TableViewcontroller.xib created by me should be initial controller

I have created TableViewController by xib not on storyboard. I have view controller which loads by default. Now I want that TableViewController as root controller. Thanks in advance.
1 first register you xib in particular viewController in which you want to load.
by register.nibLod
2 then in AppDelegate in - didFinish method make your that particular viewController as rootviewcontroller.
You can do like this.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let navigationController: UINavigationController = UINavigationController(rootViewController: YourViewController()) //where YourViewController is name of viewController which you want to use as rootViewController
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
return true
}

Tab Bar app with a split view controller - the detail page is showing first before the main page

I have created a Tab Bar App. On the first item, is a Split View Controller with a Master and Detail. When running the app, I can see the tab bar on the page however, it's showing my Detail page. Why is it not defaulting to the Master page?
I have researched some answers but no luck.
SplitViewController.swift
import UIKit
class SplitViewController: UISplitViewController,
UISplitViewControllerDelegate {
override func viewDidLoad() {
self.delegate = self
self.preferredDisplayMode = .allVisible
}
func splitViewController(
_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController: UIViewController,
onto primaryViewController: UIViewController) -> Bool {
// Return true to prevent UIKit from applying its default behavior
return true
}
Just for reference in case someone bumps into the same problem.
I had to use my Master-Detail SplitViewController app (without the tab bar) and do the following:
Add a Tab Bar Controller.
Connect the binding from Tab Bar Controller to the Split View Controller, as a view controller.
Revise AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
let tabBarViewController = self.window!.rootViewController as! UITabBarController
print(tabBarViewController.viewControllers?.count)
var splitViewController:UISplitViewController? = nil
for viewController in tabBarViewController.viewControllers! {
if viewController.title == "Master" {
splitViewController = viewController as? UISplitViewController
}
}
return true
}
Set Tab Bar Controller to be the Initial View Controller.
Hope this helps. Thanks!

NavigationViewController stack

I am concerned about NavigationViewController stack in the sense that apple documentation says that "A navigation controller object manages the currently displayed screens using the navigation stack, which is represented by an array of view controllers." And what about another NavigationController attached to the topViewController? Is it in navigation stack? Or there are two navigation stacks? enter image description here and so at the end what viewController will the top of this construction if we will call
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
guard let navController = window?.rootViewController as?
UINavigationController,
let viewController = navController.topViewController else {
return true
}

how to passing coredatastack from AppDelegate to the view controller without navigation controller

I know the way to pass coreDataStack to the viewController with navigation controller embedded by this way.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let navigationController = window!.rootViewController as! UINavigationController
let viewController = navigationController.topViewController as! ViewController
viewController.coreDataStack = coreDataStack
return true
}
I want to pass the coreDataStack to my viewController without the navigation controller,
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewControllerWithIdentifier("Home") as! Home
viewController.coreDataStack = coreDataStack
return true
}
However, the coreDataStack in the viewController found to be nil.
How can I do it?
Your code is creating a new instance of the view controller, not referencing the existing instance. You should be able to use this:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let viewController = window!.rootViewController as! ViewController
viewController.coreDataStack = coreDataStack
return true
}