【问题标题】:Programmatically switching between tabs within Swift以编程方式在 Swift 中的选项卡之间切换
【发布时间】:2014-10-09 03:50:15
【问题描述】:

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

我是 Swift 新手,并且已经解决了以下问题:

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

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

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

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

【问题讨论】:

    标签: ios xcode swift uitabbarcontroller viewcontroller


    【解决方案1】:

    如果您的window rootViewControllerUITabbarController(在大多数情况下),那么您可以在AppDelegate 文件中的didFinishLaunchingWithOptions 中访问tabbar

    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
    }
    

    这将打开带有index 的标签,在selectedIndex 中给出(1)。

    如果您在firstViewControllerviewDidLoad 中执行此操作,则需要通过标志或其他方式管理以跟踪所选选项卡。在AppDelegate 文件的didFinishLaunchingWithOptionsrootViewController 自定义类viewDidLoad 中执行此操作的最佳位置。

    【讨论】:

    • Tx 指出我!但是,我最终得到了:if let tababarController = self.window!.rootViewController as! UITabBarController? { tababarController.selectedIndex = tabIndex }
    • 你不能在TabBarViewController 中执行以下操作吗:class TabBarViewController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() selectedIndex = 1 } 在这种情况下,它只会选择 OP 想要执行的辅助选项卡。
    • 只需将as UITabBarController 替换为as! UITabBarController,它也可以在Swift 3 中使用。感谢您的回答!
    • 在 iOS 14.8 中,上面的代码有时会在 self.window 上失败,“Unexpectedly found nil while unwrapping an Optional value”!行。
    【解决方案2】:

    要扩展@codester的答案,您不需要检查然后分配,您可以一步完成:

    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
    }
    

    【讨论】:

      【解决方案3】:

      1.创建一个新类,它取代了 UITabBarController。 例如:

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

      2.在函数viewDidLoad()中加入如下代码:

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

      3.转到故事板,并将标签栏控制器的自定义类设置为这个新类。 (图中以MyVotes1为例)

      【讨论】:

      • 这在 Xcode 8.2 swift 3 中对我有用。谢谢!我的应用程序将显示 5 个选项卡的中间(第 3 个)选项卡。类 PatientTabBarController: UITabBarController { 覆盖 func viewDidLoad() { super.viewDidLoad() selectedIndex = 2 } }
      【解决方案4】:

      斯威夫特 3

      您可以将此代码添加到 tabBarController 中的默认视图控制器 (index 0):

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

      加载时,这会自动将选项卡移动到列表中的第二项,但也允许用户随时手动返回该视图。

      【讨论】:

      • 为什么不使用“tabBarController?.selectedIndex = 1”呢?
      • 您应该始终致电super.viewWillAppear()。也不需要分配给_ =
      【解决方案5】:

      viewController 必须是 UITabBarControllerDelegate 的子级。所以你只需要在SWIFT 3上添加如下代码

      self.tabBarController?.selectedIndex = 1
      

      【讨论】:

        【解决方案6】:

        在一个典型的应用程序中有一个 UITabBarController 并且它嵌入了 3 个或更多 UIViewController 作为它的选项卡。在这种情况下,如果您将 UITabBarController 子类化为 YourTabBarController,那么您可以简单地通过以下方式设置所选索引:

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

        如果您从任何其他视图导航到 YourTabBarController,那么您可以在该视图控制器的 prepare(for segue:) 方法中执行以下操作:

        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
                    }
                }
        

        我在 Xcode 10 和 Swift 4.2 中使用这种设置选项卡的方式。

        【讨论】:

          【解决方案7】:

          只是为了更新,在 iOS 13 之后,我们现在有了 SceneDelegates。因此,可以选择将所需的选项卡选择放在 SceneDelegate.swift 中,如下所示:

          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
                  }
          
              }
          

          【讨论】:

            【解决方案8】:

            斯威夫特 5

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

            tabBarController?.selectedIndex = 1
            

            如果您使用的是 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
                    }
                }
            }
            

            【讨论】:

              【解决方案9】:

              如果您想从您作为特定视图控制器的一部分编写的代码中执行此操作,例如响应按钮按下或其他操作,您可以这样做:

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

              您还可以使用 UITabBarControllerDelegate 方法添加代码来处理选项卡切换。在每个选项卡的基本视图控制器上使用标签,您可以看到自己的位置并采取相应措施:例如

              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
                  }
              }
              

              【讨论】:

                【解决方案10】:

                斯威夫特 5

                如果你的类是UITabBarController 的子类,你可以这样做:

                selectedViewController = viewControllers![yourIndex]
                

                【讨论】:

                  【解决方案11】:

                  试试

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

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-07-23
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-04-07
                    相关资源
                    最近更新 更多