在 Swift 中以编程方式设置动作监听器
Posted
技术标签:
【中文标题】在 Swift 中以编程方式设置动作监听器【英文标题】:Set Action Listener Programmatically in Swift 【发布时间】:2014-12-09 03:57:53 【问题描述】:我看到一些示例代码将相同的 OnClick 事件分配给 android 中的所有按钮(即使它们执行完全不同的操作)。如何用 Swift 做到这一点
Android 示例:
@Override
public void onCreate(Bundle savedInstanceState)
button1.setOnClickListener(onClickListener);
button2.setOnClickListener(onClickListener);
button3.setOnClickListener(onClickListener);
private OnClickListener onClickListener = new OnClickListener()
@Override
public void onClick(View v)
switch(v.getId())
case R.id.button1:
//DO something
break;
case R.id.button2:
//DO something
break;
case R.id.button3:
//DO something
break;
;
注意:我不想以编程方式创建按钮。
【问题讨论】:
How create button programmatically in Swift?的可能重复 不...我需要为多个按钮添加相同的侦听器...这不是重复的。 在每个指向同一个动作的按钮上调用addTarget方法? UIcontrol 有一个方法 -addTarget 可以指向同一个“监听器”UIControl。但是从您的代码来看,为什么不使用 4 个侦听器而不是一个确定按下哪个按钮的侦听器? @cream-corn 因为您可能有一个动态表结构,其中包含可以使用行索引映射的按钮。 【参考方案1】:在 ios 上,您没有设置监听器;您将目标(对象)和操作(方法签名,iOS 用语中的“选择器”)添加到您的 UIControl
(UIButton
是其子类):
button1.addTarget(self, action: "buttonClicked:", for: .touchUpInside)
button2.addTarget(self, action: "buttonClicked:", for: .touchUpInside)
button3.addTarget(self, action: "buttonClicked:", for: .touchUpInside)
第一个参数是目标对象,在本例中为self
。该操作是一个选择器(方法签名),基本上有两个选项(稍后会详细介绍)。 control event 有点特定于 UIControl
- .TouchUpInside
通常用于点击按钮。
现在,行动。这是以下格式之一的方法(名称由您选择):
func buttonClicked()
func buttonClicked(_ sender: AnyObject?)
要使用第一个使用“buttonClicked”,第二个(你想要的)使用“buttonClicked:”(带有尾随冒号)。 sender
将是事件的来源,也就是您的按钮。
func buttonClicked(_ sender: AnyObject?)
if sender === button1
// do something
else if sender === button2
// do something
else if sender === button3
// do something
(假设button1
、button2
和button3
是实例变量)。
考虑为每个按钮使用单独的方法,而不是使用大 switch 语句的这种方法。根据您的具体用例,两种方法都可能更好:
func button1Clicked()
// do something
func button2Clicked()
// do something
func button3Clicked()
// do something
在这里,我什至没有使用 sender
参数,因为我不需要它。
P.S.:您可以在 Storyboard 或 nib 文件中添加目标和操作,而不是以编程方式添加。为了公开您在函数前面放置IBAction
的操作,例如:
@IBAction func button1Clicked()
// do something
【讨论】:
【参考方案2】:Swift 4.*
button.addTarget(self, action: #selector(didButtonClick), for: .touchUpInside)
并且按钮触发了这个功能:
@objc func didButtonClick(_ sender: UIButton)
// your code goes here
【讨论】:
现在应该写成 #selector(buttonClicked(sender:)) 或使用 #selector(buttonClicked(:)) btnAll.addTarget(self, action: #selector(buttonClicked( i>:)), for: .touchUpInside) 然后改变你的函数,比如 func buttonClicked(_ sender : UIButton) .... 如果我为所有按钮设置了相同的功能,如何检查单击了哪个按钮? 要检查单击了哪个按钮,您在创建它们时设置了不同的标签。 button.tag = 1(或 2 或 3)。然后你使用:switch sender.tag case 1:...【参考方案3】:Swift 5 扩展解决方案
创建一个 SwiftFile "SetOnClickListener.swift" 复制粘贴此代码
import UIKit
class ClosureSleeve
let closure: () -> ()
init(attachTo: AnyObject, closure: @escaping () -> ())
self.closure = closure
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN)
@objc func invoke()
closure()
extension UIControl
func setOnClickListener(for controlEvents: UIControl.Event = .primaryActionTriggered, action: @escaping () -> ())
let sleeve = ClosureSleeve(attachTo: self, closure: action)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
如何使用 例如 buttonA 是一个 UIButton
buttonA.setOnClickListener
print("button A clicked")
【讨论】:
如何获取目标元素,例如@objc func didButtonClick(_ sender: UIButton) // 你的代码在这里 ?以上是关于在 Swift 中以编程方式设置动作监听器的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 中以编程方式创建的多个文本视图的单个 onclick 侦听器
在 Swift 中以编程方式设置 tabBarItem 标题
如何在 Swift 中以编程方式在水平线上设置约束? [关闭]
尝试在 Swift 中以编程方式设置 rightBarButton