以编程方式在 Swift 中的选项卡之间切换

我需要编写一些代码,以便在 iOS 应用程序启动时将视图切换到另一个选项卡(例如,默认显示第二个选项卡而不是第一个选项卡)。

我是斯威夫特的新成员,我想出了以下几点:

  • 代码可能应该放在第一个选项卡的 ViewController 的覆盖 func viewDidLoad ()函数中。

  • 下面的代码显示了第二个 ViewController,但是底部没有标签栏(vcOptions 是第二个 ViewController 标签项:

let vc : AnyObject! = self.storyboard.instantiateViewControllerWithIdentifier("vcOptions")
self.showViewController(vc as UIViewController, sender: vc)

我认为答案可能在于使用 UITabbarController.selectedIndex = 1,但是不太确定如何实现它。

137185 次浏览

If your window rootViewController is UITabbarController(which is in most cases) then you can access tabbar in didFinishLaunchingWithOptions in the AppDelegate file.

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
// Override point for customization after application launch.


if let tabBarController = self.window!.rootViewController as? UITabBarController {
tabBarController.selectedIndex = 1
}


return true
}

This will open the tab with the index given (1) in selectedIndex.

If you do this in viewDidLoad of your firstViewController, you need to manage by flag or another way to keep track of the selected tab. The best place to do this in didFinishLaunchingWithOptions of your AppDelegate file or rootViewController custom class viewDidLoad.

To expand on @codester's answer, you don't need to check and then assign, you can do it in one step:

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
// Override point for customization after application launch.


if let tabBarController = self.window!.rootViewController as? UITabBarController {
tabBarController.selectedIndex = 1
}


return true
}

1.Create a new class which supers UITabBarController. E.g:

class xxx: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
}

2.Add the following code to the function viewDidLoad():

self.selectedIndex = 1; //set the tab index you want to show here, start from 0

3.Go to storyboard, and set the Custom Class of your Tab Bar Controller to this new class. (MyVotes1 as the example in the pic)

enter image description here

Swift 3

You can add this code to the default view controller (index 0) in your tabBarController:

    override func viewWillAppear(_ animated: Bool) {
_ = self.tabBarController?.selectedIndex = 1
}

Upon load, this would automatically move the tab to the second item in the list, but also allow the user to manually go back to that view at any time.

The viewController has to be a child of UITabBarControllerDelegate. So you just need to add the following code on SWIFT 3

self.tabBarController?.selectedIndex = 1

In a typical application there is a UITabBarController and it embeds 3 or more UIViewController as its tabs. In such a case if you subclassed a UITabBarController as YourTabBarController then you can set the selected index simply by:

selectedIndex = 1 // Displays 2nd tab. The index starts from 0.

In case you are navigating to YourTabBarController from any other view, then in that view controller's prepare(for segue:) method you can do:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
if segue.identifier == "SegueToYourTabBarController" {
if let destVC = segue.destination as? YourTabBarController {
destVC.selectedIndex = 0
}
}

I am using this way of setting tab with Xcode 10 and Swift 4.2.

Just to update, following iOS 13, we now have SceneDelegates. So one might choose to put the desired tab selection in SceneDelegate.swift as follows:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {


var window: UIWindow?


func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {


guard let _ = (scene as? UIWindowScene) else { return }


if let tabBarController = self.window!.rootViewController as? UITabBarController {
tabBarController.selectedIndex = 1
}


}

Swift 5

//MARK:- if you are in UITabBarController
self.selectedIndex = 1

or

tabBarController?.selectedIndex = 1

if you are using UITabBarController

// UITabBarDelegate
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print("Selected item")
if kAppDelegate.isLoggedIn == false {
switch tabBar.selectedItem?.title {
case "Favorite":
DispatchQueue.main.async {
self.selectedIndex = 0
DispatchQueue.main.async {
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { timer in
self.showAlert(Constants.GlobalConstants.APP_NAME, message: "You are not login.")
}
}
}
break
case "Track Order":
            

DispatchQueue.main.async {
self.selectedIndex = 0
DispatchQueue.main.async {
Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { timer in
self.showAlert(Constants.GlobalConstants.APP_NAME, message: "You are not login.")
}
}
}
break
default:
break
}
}
}

If you want to do this from code that you are writing as part of a particular view controller, like in response to a button press or something, you can do this:

@IBAction func pushSearchButton(_ sender: UIButton?) {
if let tabBarController = self.navigationController?.tabBarController  {
tabBarController.selectedIndex = 1
}
}

And you can also add code to handle tab switching using the UITabBarControllerDelegate methods. Using tags on the base view controllers of each tab, you can see where you are and act accordingly: For example

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
    

// if we didn't change tabs, don't do anything
if tabBarController.selectedViewController?.tabBarItem.tag ==  viewController.tabBarItem.tag {
return false
}
    

if viewController.tabBarItem.tag == 4096 { // some particular tab
// do stuff appropriate for a transition to this particular tab
}
else if viewController.tabBarItem.tag == 2048 { // some other tab
// do stuff appropriate for a transition to this other tab
}
}

Swift 5

If your class is a subclass of UITabBarController, you can just do:

selectedViewController = viewControllers![yourIndex]

Try

DispatchQueue.main.async {
self.tabBarController?.selectedIndex = 1
}

From any where in-app you can switch between tabs

struct Constants{
static var tabbarVC : TabbarViewController!

}

During initialization of tab bar view controller store its reference to Constants.tabbarVC

     let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "TabbarViewController") as! TabbarViewController
Constants.tabbarVC = vc

Finally by using this reference you can switch tabs

Constants.tabbarVC.selectedIndex = 2