How can I switch to some tab in UITabBarController using StoryBoard? I have tried the code below but without success (the tab is not selected):
self.tabBar.selectedIndex = 3;
Honestly I used nib files without StoryBoard and this code above worked fine in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions
:(NSDictionary *)launchOptions
but now I can't set the tab programatically. Maybe there is another problem that is not connected to selecting the tab. How can I switch tabs?
Grab your instance of UITabBarController then set the selectedViewController property:
yourTabBarController.selectedViewController=[yourTabBarController.viewControllers objectAtIndex:3];//or whichever index you want
Alexander, I think your problem is getting correct instance of your tab bar. If your tab bar is your root view controller, then you can do it like this in your appdelegate if didFinishLoading method:
UITabBarController *tabBar = (UITabBarController *)self.window.rootViewController;
[tabBar setSelectedIndex:3];
Give it a try and tell me the result please.
*Swift Comment - 18 months later if you convert Yanchi's solution into Swift in your appDelegate you'll get the expected result. The Swift translation is:
let tabBar: UITabBarController = self.window?.rootViewController as! UITabBarController
tabBar.selectedIndex = 1
This will work in stroryboard too...
[self.tabBarController setSelectedIndex:3]; with this add UITabBarControllerDelegate in .h
and then use this delegate method
- (BOOL)tabBarController:(UITabBarController *)theTabBarController shouldSelectViewController:(UIViewController *)viewController
{
return (theTabBarController.selectedViewController != viewController);
}
Swift 4.1
In your TabBarViewController class, you can add this key line
self.selectedIndex = 0
You can achieve this also using storyboards only. Ctrl-drag from the tabBarController to your ViewController(s), and select 'Relationship Segue, View controllers'. The first ViewController you select will be the default/initial ViewController.
I'm using IBInspected in LSwift:
extension UITabBarController {
#IBInspectable var selected_index: Int {
get {
return selectedIndex
}
set(index) {
selectedIndex = index
}
}
}
Swift 5.3
Let tabBar be an instance of UITabBarController then :
tabBar.selectedViewController = tabBar.viewControllers![2]
Note:
Instead of 2, put your desired viewController's index
Here is what I do (Swift 5.x):
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let tabBarController = self.window?.rootViewController as? UITabBarController {
if let viewControllers: [UIViewController] = tabBarController.viewControllers {
tabBarController.selectedIndex = viewControllers.count-1
}
}
return true
}
You can also set the default tab in "User Defined Runtime Attributes" using storyboard.
Select your Tab Bar Controller from storyboard, in the right pane select Identity Inspector and add an attribute:
Key Path : selectedIndex
Type : Number
Value : 2 ( whatever number you want )
Related
I have implemented a tabViewController with some pages. one of those page is a tableview controller. after clicking on tableview item i am opening another viewController. Now i want to go back to that specific page. the selectedIndex of that tab Page is 1.
How can i do this?
Thanks for your help
store board
Try this
let tabBar: UITabBarController = self.window?.rootViewController as! UITabBarController
tabBar.selectedIndex = 1
If you are outside from tabBar Controller.
self.tabBarController?.selectedIndex = 1
If you are already in tabBar Controller and move to another tabBar Controller. Go to the ViewDid of TabBar method and paste the code.
override func viewDidLoad() {
super.viewDidLoad()
self.selectedIndex = 1
}
If you want the user to be able to go back to tableViewController after clicking on a cell you should use a navigationController instead.
You are using UITabBarController as rootViewController then can do this:
if let appDelegate = UIApplication.shared.delegate as? AppDelegate{
if let rootTabBarController = appDelegate.window?.rootViewController as? UITabBarController{
rootTabBarController.selectedIndex = 1
}
}
So I have a segue from ViewController to SecondViewController. This segue is triggered by a UIButton in ViewController and the modally presents SecondViewController. The Segue's Identifier is set ("SegueIdentifier") and I am able to call the segue programatically from within my ViewController.
When I try to do the same in my AppDelegate, I get the error that the compiler can't find a segue with the Identifier I set.
let viewController = ViewController()
viewController.performSegueWithIdentifier("SegueIdentifier", sender: nil)
Again, I literally copied and pasted the performSegueWithIdentifier method call from the aforementioned method in ViewController in which I also call performSegueWithIdentifier for the same segue and it works.
Any ideas?
In my one project I am managing this situation like,
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSString *identifier;
BOOL isSaved = [[NSUserDefaults standardUserDefaults] boolForKey:#"loginSaved"];
if (isSaved)
{
identifier=#"home1";
}
else
{
identifier=#"dis1";
}
UIStoryboard * storyboardobj=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *screen = [storyboardobj instantiateViewControllerWithIdentifier:identifier];
[self.window setRootViewController:screen];
return YES;
}
It is in objective c and just for reference. If it can help you :)
Update :
In swift something like,
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var identifier: String = String()
let isSaved = NSUserDefaults.standardUserDefaults().boolForKey("loginsaved")
if isSaved
{
identifier = "home1"
}
else{
identifier = "dis1"
}
let storyboardobj: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let screen: UIViewController = storyboardobj.instantiateViewControllerWithIdentifier(identifier)
self.window!.rootViewController = screen
// Override point for customization after application launch.
return true
}
Hope this will help :)
If you are not trying to show your initial view then do like this:
UIApplication.sharedApplication().keyWindow?.rootViewController.performSegueWithIdentifier("SegueIdentifier", sender: nil)
And also it depends that you segue is set to your RootViewController. Please check that also before you do this.
Segue connection has some info with it like Source Controller, Destination Controller. So while you are calling the performSegue method from ViewController class, it will work because that class has the info of this Segue connection.
While you are calling that same Segue method from App Delegate, it will not work. Because App Delegate class doesn't have the info or definition about that Segue object.
You should also check whether the calling object comes under Navigation Controller or not.
A storyboard segue has to be tied to the specific viewController that you are trying to segue from. So you have to have an instance of the current view controller on the screen. You may use the UIApplication.sharedApplication().keyWindow?.rootViewController
Method to get access to the rootViewController in the window, however if you presented a view controller above the rootViewController and you want to perform the segue on the presented view controller you have to access the rootViewController.presentedViewController. And since you may have multiple presentedViewControllers, what you do is this:
//get the root view controller
var currentViewController = UIApplication.sharedApplication().keyWindow?.rootViewController
//loop over the presented view controllers and until you get the top view controller
while currentViewController.presentedViewController != nil{
currentViewController = currentViewController.presentedViewController
}
//And finally
currentViewController.performSegueWithIdentifier("identifier", sender: nil)
I'm using the Material Framework by CosmicMind. Currently I'm trying to replace the ViewController once a row is selected in the SideNavigationController. Unfortunately I can't figure out how to do this. There're similar question here on StackOverflow (#1) unfortunately the solutions don't work for me.
Following my code in the AppDelegate.swift class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myViewController = storyboard.instantiateViewControllerWithIdentifier("MyViewController")
let navigationController: NavigationController = AppNavigationController(rootViewController: myViewController)
let sideNavigationController: SideNavigationController = SideNavigationController(rootViewController: navigationController, leftViewController: AppLeftViewController())
// further code
return true
}
With this code everything works fine. The ViewController (MyViewController) is shown.
Now I'm trying to replace the MyViewController with MySecondViewController however this doesn't work. Following the code I've been using:
sideNavigationController?.transitionFromRootViewController(MySecondViewController())
The result is that the Toolbar disappears and I can't close the SideNavigationController anymore. So I've tried the following:
let navigationController: NavigationController = AppNavigationController(rootViewController: MySecondViewController())
sideNavigationController?.transitionFromRootViewController(navigationController)
With this code the Toolbar is visible once again but the problem with the SideNavigationController remains -> means: It can't be closed.
tl;dr
How do I replace the rootViewController of the NavigationController properly?
The NavigationController is a subclass of UINavigationController. So changing the rootViewController is as iOS made it. For example:
navigationController?.pushViewController(MySecondViewController(), animated: true)
The SideNavigationController offers the ability to transition its rootViewController. This is different, as the SideNavigationController uses child UIViewControllers and swaps them when asked. For example:
sideNavigationController?.transitionFromRootViewController(MySecondViewController())
Sometimes, people use the sideNavigationController to early. For example, you instantiate a new UIViewController, and place the sideNavigationController code in the videDidLoad method. This won't work since the new UIViewController was not yet added to the sideNavigationController view hierarchy. To solve this, use the viewWillAppear method.
The last situation to consider is when you want to load a new UIViewController in the rootViewController of the NavigationController from the sideNavigationController. In order to do this, and let's consider that the sideNavigationController's rootViewController is the NavigationController, you would need to do this:
(sideNavigationController?.rootViewController as? NavigationController)?.pushViewController(MySecondViewController(), animated: true)
This should help you out :)
I am having problem in pushing ViewController from AppDelegate when user pressed the Notification
Below is my code, but this code Crashes because the navigationController is nil
func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
var rootViewController = self.window!.rootViewController;
let customDetailsViewController = CustomDetailsViewController();
rootViewController?.navigationController!.pushViewController(customDetailsViewController, animated: true);
}
Any idea? Thank you!!
If your navigation controller is nil, then your rootViewController (the one with the arrow in your Storyboard) is not inside a NavigationController. Can you post a screenshot of the relevant part of your Storyboard?
EDIT:
As you are using RESideController, you'll have a RootViewController not connected to anything in your Storyboard. That RootViewController conforms to ``protocol and you have some code like:
#implementation FASRootViewController
- (void)awakeFromNib
{
self.menuPreferredStatusBarStyle = UIStatusBarStyleLightContent;
self.scaleContentView = NO;
self.scaleMenuView = NO;
self.panGestureEnabled = YES;
self.contentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"contentViewController"];
self.rightMenuViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"rightMenuViewController"];
self.delegate = (id<RESideMenuDelegate>)self.rightMenuViewController;
}
To "launch" your View controllers your need to add a identifier in the Storyboard
Also, this View Controller should be a UINavigationController (not your first "content" view controller)
Recently, I want to make an App for self-study and that App looks like Contacts App in iOS. First, I have two UITableViewControllers connecting to UITabBarViewController. Then I want to embed UINavigationController with those 2 tableviews by coding (In this case, I don't want to embed it in Storyboard by design). But I'm stuck with it. Here is my code in AppDelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let tabBar : UITabBarViewController = UITabBarViewController()
let tableView1 : UITableViewController = UITableViewController()
let nav = UINavigationController(rootViewController: tableView1)
let tableView2 : UITableViewController = UITableViewController()
let nav2 = UINavigationController(rootViewController: tableView2)
tabBar.viewControllers = [nav, nav2]
self.window?.rootViewController = tabBar
return true
}
And the result always displays the first tableView1. How can I make it to display two tab options(on the bottom of the view) in UITabBarViewController? If I make it by designing in Storyboard, I'm sure it will work fine. But by coding, I've no idea how to fix it.
Please kindly guide me. Thanks in advance!
There is no UITabBarViewController in UIKit. It is called UITabBarController. Your ViewControllers need to have NavigationItems. If you display them like in your code you will have a Tabbar on bottom but without anything visible on it. In your case the NavigationControllers are the ones where you need to define nav.navigationItem.title = ...
EDIT:
and I realized you are not initializing the window. This is not related to your other problem but you would not see anything with your code. So you have to change it to:
self.window = UIWindow(frame: UIScreen.mainScreen().bounds);
self.window?.rootViewController = tabBar
self.window?.makeKeyAndVisible();