以编程方式从 UIBarButtonItem

Posted

技术标签:

【中文标题】以编程方式从 UIBarButtonItem【英文标题】:Programmatically segue from UIBarButtonItem 【发布时间】:2016-11-30 14:38:44 【问题描述】:

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

我以编程方式创建这些按钮,而不是在每个相应的视图控制器 (VC) 中编写代码,我决定编写一个 Helper 类来创建这些按钮。

// 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. 


然后我从每个 VC 的viewDidLoad() 中调用Helper.loadNavBarItems(vc: self)

我现在要做的是在按下其中一个按钮时触发 segue(假设它是配置文件按钮)。所以,我需要定义profile.action。因此,在 Helper 类中,我必须编写一个函数 segueToProfile,它接受一个视图控制器 (vc) 并运行 performSegueWithIdentifier

问题是,我不完全了解如何通过选择器传递不同类型的参数,而且我可能不擅长谷歌搜索,但我找不到任何足够接近我的问题让我了解如何实现这个。

非常感谢您的帮助。

供参考,this is the structure of my Storyboard。

编辑:如故事板结构截图所示,我已经创建了从三个视图控制器到目标视图控制器的转场。

【问题讨论】:

您愿意通过选择器发送什么样的参数?同样在您的故事板模拟中,您正在展示导航控制器。所以你应该明白destinationController 将是NavigationController,而不是ViewCotnroller。另一件事是,您可能应该为 UIViewController 创建一个扩展并替换所有创建和分配 BarButtons 的代码。这样你就可以避免将 UIViewController 参数传递给loadNavBarItems func @noir_eagle 谢谢,但我的问题在于理解 UIBarButtonItem 操作和选择器。我试图在点击其中一个 UIBarButtonItems 时触发 segue,并且我试图弄清楚在使用 profileButton.action 时如何将参数传递给选择器 这个导航控制器在每个页面上都有这些按钮吗?还是只有一个 ViewController? 按钮位于嵌套在导航控制器中的每个视图控制器(类型UIViewController)上。 【参考方案1】:

创建 barButtonItem:

navigationItem.rightBarButtonItem = UIBarButtonItem(title: "?", style: .plain, target: self, action: #selector(ProfileButtonTapped))

为 barButtonItem 创建动作和 segue:

 func ProfileButtonTapped()  
    print("Button Tapped")   
    performSegue(withIdentifier: "YourSegueIdentifierName", sender: self) 
    //If you want pass data while segue you can use prepare segue method
   

注意:对于perform segue,您必须从情节提要中提供segue identifier name

输出:

更新:

如果您想在不使用 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)

【讨论】:

【参考方案2】:

我不知道我是否理解您的问题,但是对于使用 segue 在 vi​​ewControllers 之间传递数据(在您的情况下嵌入在 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。 好的,但是您在为新控制器触发 segue 时遇到问题吗?因为在这种情况下,从情节提要中,您可以使用 control+drag 到您的控制器并检查 (Relationship segue (view controllers)) 并自动 Xcode 创建从 tabbarController 到 UIViewController 的单个 segue【参考方案3】:

要向UIBarButton 添加动作,您应该使用它的初始化器之一。 例如

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

除了 title 之外,您还可以为该按钮设置一个 Image。

【讨论】:

谢谢,但你能告诉我如何添加一个接受参数的动作吗?【参考方案4】:

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

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

didPressLeftButton 是一个函数:

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

【讨论】:

谢谢,但你能告诉我如何添加一个带参数的动作吗? 看看这里的教程,他们有几个带参数的好例子:bignerdranch.com/blog/hannibal-selector 只是另一个想法@FaresK.A. - 你真的需要传递参数吗?如果每个视图都有自己的导航按钮,则可以将功能 didPressLeft、didPressRight 附加到视图控制器。为了使其更可重用,您可以使用处理创建按钮的基本视图控制器对其进行子类化。

以上是关于以编程方式从 UIBarButtonItem的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式从 UIBarButtonItem

如何以编程方式从动态 JObject 获取属性

iOS - 从 XIB 文件中引用和以编程方式移动视图

以编程方式构建 - 未从程序集中加载“TransformTemplates”任务

以编程方式从 PEM 获取 KeyStore

Android:以编程方式从数组创建微调器