首页 > 解决方案 > 为 x 数量的按钮添加目标并返回到 tabBarController

问题描述

到目前为止,这是我的代码:

    func getFriends() {
        let numOfFriends = userDefaults.integer(forKey: "numOfFriends")
        if numOfFriends > 0{
            //Show friend Labels
            let friendNames = userDefaults.array(forKey: "friendNames") as! Array<String>
            for x in 0...friendNames.count - 1 {
                let button = UIButton()
                button.setTitle(friendNames[x], for: .normal)
                button.setTitleColor(.black, for: .normal)
                button.addTarget(self, action: #selector(self.tapped(_:)), for: .touchUpInside)
                stackView.addArrangedSubview(button)
            }
            checkFriends()
        }
        else{
            // show a label syaing no friends
            let label = UILabel()
            label.text = "You have no friends :("
            stackView.addArrangedSubview(label)
            checkFriends()
        }
    }
    
    @objc func tapped(_ sender: UIButton){
        if sender.currentTitle != nil {
            //Set active friend
            userDefaults.set(sender.currentTitle, forKey: "currentFriend")
            userDefaults.synchronize()
            //Go to FriendInfoViewController
        }
    }

因此,当getFriends()被调用时,它会创建friendNames.count大量按钮。我希望所有这些按钮都转到另一个名为FriendInfoViewController. 当前 ViewController 连接到 Navigation Controller 并且连接到 TabBarController。

我面临的问题是如何转到下一个视图控制器然后返回它仍然在 TabBarController

标签: swiftxcodestoryboardviewcontroller

解决方案


这就是我将如何设置故事板和视图控制器以按照您的要求行事。

故事板

这包括一个作为根视图控制器的选项卡栏控制器,其中包含两个链接到视图控制器的选项卡。Xcode 在创建标签栏控制器时默认提供这两个。

对于两个选项卡的视图控制器,我将它们都嵌入了它们自己的导航控制器中。您可以通过在界面构建器中选择 View Controller 来完成此操作,然后从 Xcode 菜单中选择 Editor -> Embed In -> Navigation Controller。这使我们能够为每个选项卡独立添加和导航到我们喜欢的任意数量的视图控制器。

在此处输入图像描述

对于这两个视图控制器,创建视图控制器子类,我命名我的 Tab1ViewController 和 Tab2ViewController,并记住更改 Xcode 的 Identity Inspector 中的 Class 设置以匹配每个。

在此处输入图像描述

最初的问题询问如何将数据传递给新的视图控制器,并有能力返回。这可以通过多种方式实现,通过 Segues 是一种选择,但我更喜欢手动执行我的操作以提高可见性。

因此,假设包含要传递的数据的数组已填充,我们将其传递给 FriendInfoViewController,这是我们想要导航到的视图,当我们从情节提要中引用它时

编码:

class Tab1ViewController: UIViewController {

    var friendNames: [String] = [] // array for holding the data that needs to be passed
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }


    @IBAction func getFriends(_ sender: Any) {

        self.friendNames = ["David", "Sally", "Pete", "Michael", "Chris"] // populate the array with data

        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil) // create a reference to the storyboard
        let friendInfoViewController = storyBoard.instantiateViewController(withIdentifier: "FriendInfoViewController") as! FriendInfoViewController // instantiate an instance of the viewcontroller we want to navigate to
        
        // populate the matching array in the new view controller with the array containing the data we wish to pass
        friendInfoViewController.friendNames = self.friendNames 

        // create a reference to the navigation controller connected to the viewcontroller we are currently in
        guard let currentNavController = tabBarController?.selectedViewController as? UINavigationController  else {
            fatalError("Failed to detect navigation controller.")
        }
        
        // display the newly created view controller
        currentNavController.pushViewController(friendInfoViewController, animated: true)
    }
}

Tab2ViewController 是作为精确副本创建的,唯一的区别是当 FriendInfoViewController 显示时,Tab Bar 是隐藏的。为了以编程方式实现这一点,您可以添加它。

friendInfoViewController.hidesBottomBarWhenPushed = true // Here is how you hide the tabs

为了完整起见,FriendInfoViewController 看起来像这样。注意我们有friendNames 数组,它是从Tab1ViewController 或Tab2ViewController 接收数据的数组。要注意的另一件事是包含一个链接到一个动作的按钮,该动作要求导航控制器删除 FriendInfoViewController(本身)并动画回到根视图,显示选项卡及其各自的视图控制器。

class FriendInfoViewController: UIViewController, UINavigationControllerDelegate {

    var friendNames: [String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print(friendNames) // note you have access to friendNames anywhere in the class 
    }
    
    
    @IBAction func goBackAction(_ sender: Any) {
        self.navigationController?.popViewController(animated: true)
    }
}

这是我作为项目创建的示例的链接

标签栏导航示例


推荐阅读