以编程方式从 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 在 viewControllers 之间传递数据(在您的情况下嵌入在 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的主要内容,如果未能解决你的问题,请参考以下文章