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

Posted

技术标签:

【中文标题】以编程方式在 Swift 中的选项卡之间切换【英文标题】:Programmatically switching between tabs within 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,但不太清楚如何实现。

【问题讨论】:

【参考方案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

【讨论】:

以上是关于以编程方式在 Swift 中的选项卡之间切换的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式切换到另一个选项卡不会更改 NavigationBar 标题

以编程方式更改 TabViewController 中的选定选项卡

以编程方式移除焦点?

以编程方式从模态视图控制器切换父选项卡

以编程方式使用选项卡更改片段的选项卡索引

如何以编程方式使用 Swift 3 在所有视图控制器中显示选项卡栏?