以编程方式从UIBarButtonItem进行segue

4
我有三个视图控制器,每个控制器的导航栏左右两侧都有两个按钮,如下图所示。

Example VC

我以编程方式创建了这些按钮,为了避免在每个视图控制器中重复编写代码,我决定编写一个帮助类来创建这些按钮。
// Note: I am using FontAwesome as a third-party library.

class Helper: NSObject {

    static func loadNavBarItems(vc: UIViewController) {
        let profileButton = UIBarButtonItem()
        let addButton = UIBarButtonItem()

        let attributes = [NSFontAttributeName: UIFont.fontAwesome(ofSize: 20)] as [String: Any]

        profileButton.setTitleTextAttributes(attributes, for: .normal)
        addButton.setTitleTextAttributes(attributes, for: .normal)

        profileButton.title = String.fontAwesomeIcon(name: .userCircle)
        addButton.title = String.fontAwesomeIcon(name: .plus)

        vc.navigationItem.leftBarButtonItem = profileButton
        vc.navigationItem.rightBarButtonItem = addButton
    }

    func segueToProfile(vc: UIViewController) { // I need help here. }

}

我会在每个 ViewController 的 `viewDidLoad()` 中调用 `Helper.loadNavBarItems(vc: self)`。
现在我想要的是,在按下其中一个按钮时(假设是“Profile”按钮),触发一个 segue。所以,我需要定义 `profile.action`。因此,在 Helper 类中,我需要编写一个名为 `segueToProfile` 的函数,该函数接受一个视图控制器参数(`vc`),并运行 `performSegueWithIdentifier`。
问题在于,我不完全理解如何通过选择器传递不同类型的参数,而且我可能不擅长搜索,因为我找不到与我的问题足够接近的任何问题,以便我理解如何实现这一点。
非常感谢您的帮助。
供参考,这是我的故事板结构
编辑:如故事版结构截图所示,我已经从每个 ViewController 创建了一个 segue 到目标 ViewController。

你想通过选择器发送哪种类型的参数?另外,在你的故事板模拟中,你正在展示导航控制器。因此,你应该明白目标控制器将是导航控制器,而不是视图控制器。还有一件事情,可能你应该为UIViewController创建一个扩展,并将所有创建和分配BarButtons的代码替换到其中。这样,你就可以避免将UIViewController参数传递到loadNavBarItems函数中。 - haik.ampardjian
@noir_eagle 谢谢,但我的问题在于理解UIBarButtonItem的动作和选择器。我正在尝试在点击UIBarButtonItems之一时触发一个segue,并且我正在尝试弄清楚如何在使用profileButton.action时传递参数给选择器。 - Fares K. A.
这个导航控制器是否在每个页面上都有那些按钮?还是只在一个ViewController中? - Kayla Galway
按钮位于每个视图控制器(类型为UIViewController)上,这些视图控制器嵌套在导航控制器中。 - Fares K. A.
4个回答

1
创建barButtonItem的方法如下:
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: #selector(ProfileButtonTapped))

创建与barButtonItem相关的操作和连线:
 func ProfileButtonTapped() { 
    print("Button Tapped")   
    performSegue(withIdentifier: "YourSegueIdentifierName", sender: self) 
    //If you want pass data while segue you can use prepare segue method
   }

注意: 要执行segue,您需要从您的storyboard中提供一个segue标识符名称。

enter image description here

输出:

enter image description here

更新:

如果您想在没有segue的情况下连接destVC,您可以使用以下方法:

注意:要使用以下方法,您必须在identity inspector中设置storyBoard Id

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let DestVC = storyboard.instantiateViewController(withIdentifier: "DestVcName") as! DestVcName //UINavigationController
self.present(DestVC, animated: true, completion: nil)

0
我不确定我是否理解了你的问题,但是如果你想在视图控制器之间传递数据(在你的情况下嵌入了一个UINavigationController),你可以这样做:
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
  if(segue.identifier == "yourIdentifier"){
        let navPreview : UINavigationController = segue.destination as! UINavigationController
        let preview : YourViewController = navPreview.viewControllers[0] as! YourViewController
}}

谢谢Alessio,但我的问题与UIBarButtonItem的操作和选择器有关。我正在尝试在点击其中一个UIBarButtonItems时触发一个segue。 - Fares K. A.
好的,但是你有没有在触发新控制器的segue时遇到问题?因为在这种情况下,从storyboard中,你可以使用控件+拖动到你的控制器,并勾选(Relationship segue(view controllers)),自动Xcode会从tabbarController创建单个segue到UIViewController。 - Alessio Campanelli

0

要将操作添加到UIBarButton,您应该使用其中一个初始化程序。例如

let profileButton = UIBarButtonItem(title: "Your title", style: .done, target: self, action: #selector("Call your function to push View controller"))

你可以将一个图片设置为按钮,而不是标题。


谢谢,但您能向我展示如何添加一个带参数的操作吗? - Fares K. A.

0

您可以使用选择器创建barButtonItems:

 let leftBarButton = UIBarButtonItem(image: image, landscapeImagePhone: image, style: UIBarButtonItemStyle.bordered, target: self, action: #selector(didPressLeftButton))

其中 didPressLeftButton 是一个函数:

 func didPressLeftButton(){
        print("Did press left button")
 }

谢谢,但你能给我展示一下如何添加一个带参数的动作吗? - Fares K. A.
请看这里的教程,它们有一些带参数的好例子:https://www.bignerdranch.com/blog/hannibal-selector/ - Paweł
另一个想法@FaresK.A. - 你真的需要传递参数吗?如果每个视图都有自己的导航按钮,也许将didPressLeft、didPressRight功能附加到视图控制器上。为了使其更具可重用性,您可以使用基础视图控制器对其进行子类化,以处理创建按钮的工作。 - Paweł

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接