我正在尝试将一个额外的参数传递给buttonClicked操作,但无法确定Swift中的语法应该是什么。
button.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
任何我的buttonClicked方法:
func buttonClicked(sender:UIButton)
{
println("hello")
}
任何想法?
感谢您的帮助。
答案 0 :(得分:150)
您无法在addTarget:
中传递自定义参数。另一种方法是设置按钮的tag
属性,并根据标记进行操作。
button.tag = 5
button.addTarget(self, action: "buttonClicked:",
forControlEvents: UIControlEvents.TouchUpInside)
或者 Swift 2.2 以及更高版本:
button.tag = 5
button.addTarget(self,action:#selector(buttonClicked),
forControlEvents:.TouchUpInside)
现在根据tag
属性
@objc func buttonClicked(sender:UIButton)
{
if(sender.tag == 5){
var abc = "argOne" //Do something for tag 5
}
print("hello")
}
答案 1 :(得分:66)
如果要向buttonClicked方法发送其他参数,例如indexPath或urlString,则可以对UIButton进行子类化:
class subclassedUIButton: UIButton {
var indexPath: Int?
var urlString: String?
}
确保将身份检查器中的按钮类更改为subclassedUIButton。您可以使用sender.indexPath
或sender.urlString
。
注意:如果您的按钮位于单元格内,您可以在cellForRowAtIndexPath方法(创建按钮的位置)中设置这些附加参数的值。
答案 2 :(得分:22)
我感谢大家说使用标签,但实际上你需要扩展UIButton类并简单地在那里添加对象..
标签是一种无望的方式。像这样扩展UIButton(在Swift 4中)
import UIKit
class PassableUIButton: UIButton{
var params: Dictionary<String, Any>
override init(frame: CGRect) {
self.params = [:]
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
self.params = [:]
super.init(coder: aDecoder)
}
}
那么你的电话可能是电话(注意冒号&#34;:&#34;在Selector(("webButtonTouched:"))
中)
let webButton = PassableUIButton(frame: CGRect(x:310, y:40, width:40, height:40))
webButton.setTitle("Visit",for: .normal)
webButton.addTarget(self, action: #selector(YourViewController.webButtonTouched(_:)), for:.touchUpInside)
webButton.params["myvalue"] = "bob"
然后终于抓住了这一切
@IBAction func webButtonTouched(_ sender: PassableUIButton) {
print(sender.params["myvalue"] ?? "")
}
你这样做一次并在整个项目中使用它(你甚至可以让子类有一个通用的&#34;对象&#34;并把你喜欢的任何东西放到按钮中!)。或者使用上面的示例将无穷无尽的键/字符串参数放入按钮中。对于包含网址,确认消息方法等内容非常有用
顺便说一句,SO
社区意识到这一点很重要,整整一代的不良做法都会因为惊人的问题而在互联网上进行粘贴那些不了解/没有被教导/错过object extensions
答案 3 :(得分:9)
对于Swift 3.0,您可以使用以下
button.addTarget(self, action: #selector(YourViewController.YourMethodName(_:)), for:.touchUpInside)
func YourMethodName(_ sender : UIButton) {
print(sender.tag)
}
答案 4 :(得分:5)
在Swift 3中创建一个这样的选择器:
button.addTarget(self, action: #selector(ViewController.multipleParamSelector(_:secondParams:)), for: .touchUpInside)
并抓住这样的事件:
func multipleParamSelector(_ sender: AnyObject, secondParams: AnyObject) {
}
答案 5 :(得分:5)
Swift 4.2
结果:
testButton.on(.touchUpInside) { (sender, event) in
// You can use any reference initialized before the code block here
// You can access self by adding [weak self] before (sender, event)
// You can then either make self strong by using a guard statement or use a optional operator (?)
print("user did press test button")
}
在文件UIButton+Events.swift
中,我为UIButton
创建了一个扩展方法,该方法将UIControl.Event
绑定到名为EventHandler
的完成处理程序:
import UIKit
fileprivate var bindedEvents: [UIButton:EventBinder] = [:]
fileprivate class EventBinder {
let event: UIControl.Event
let button: UIButton
let handler: UIButton.EventHandler
let selector: Selector
required init(
_ event: UIControl.Event,
on button: UIButton,
withHandler handler: @escaping UIButton.EventHandler
) {
self.event = event
self.button = button
self.handler = handler
self.selector = #selector(performEvent(on:ofType:))
button.addTarget(self, action: self.selector, for: event)
}
deinit {
button.removeTarget(self, action: selector, for: event)
if let index = bindedEvents.index(forKey: button) {
bindedEvents.remove(at: index)
}
}
}
private extension EventBinder {
@objc func performEvent(on sender: UIButton, ofType event: UIControl.Event) {
handler(sender, event)
}
}
extension UIButton {
typealias EventHandler = (UIButton, UIControl.Event) -> Void
func on(_ event: UIControl.Event, handler: @escaping EventHandler) {
bindedEvents[self] = EventBinder(event, on: self, withHandler: handler)
}
}
之所以我使用自定义类来绑定事件,是为了能够在以后取消定义按钮时释放引用。这样可以防止可能发生的内存泄漏。在UIButton
的扩展名中这是不可能的,因为不允许我实现属性或deinit
方法。
答案 6 :(得分:2)
如果您有像我这样的按钮循环,您可以尝试这样的事情
var buttonTags:[Int:String]? // can be [Int:Any]
let myArray = [0:"a",1:"b"]
for (index,value) in myArray {
let button = // Create a button
buttonTags?[index] = myArray[index]
button.tag = index
button.addTarget(self, action: #selector(buttonAction(_:)), for: .touchDown)
}
@objc func buttonAction(_ sender:UIButton) {
let myString = buttonTags[sender.tag]
}
答案 7 :(得分:2)
Swift 4.0代码(我们再来一次)
被调用的动作应该标记为这样,因为这是将函数导出为客观c语言的swift函数的语法。
@objc func deleteAction(sender: UIButton) {
}
创建一些工作按钮:
let deleteButton = UIButton(type: .roundedRect)
deleteButton.setTitle("Delete", for: [])
deleteButton.addTarget(self, action: #selector(
MyController.deleteAction(sender:)), for: .touchUpInside)
答案 8 :(得分:0)
适用于Swift 2.X及以上
button.addTarget(self,action:#selector(YourControllerName.buttonClicked(_:)),
forControlEvents:.TouchUpInside)
答案 9 :(得分:0)
Swift 3.0代码
self.timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector:#selector(fetchAutocompletePlaces(timer:)), userInfo:[textView.text], repeats: true)
func fetchAutocompletePlaces(timer : Timer) {
let keyword = timer.userInfo
}
您可以在&#39; userinfo&#39;中发送值并将其用作函数中的参数。
答案 10 :(得分:0)
Swift 5.0代码
我使用theButton.tag,但是如果我有很多类型的选项,它的开关盒会很长。
theButton.addTarget(self, action: #selector(theFunc), for: .touchUpInside)
theButton.frame.name = "myParameter"
。
@objc func theFunc(sender:UIButton){
print(sender.frame.name)
}
答案 11 :(得分:0)
这更是一个重要的评论。开箱即用地共享sytanx的引用。对于黑客解决方案,请查看其他答案。
Per Apple's docs, Action Method Definitions必须是这三个之一。其他任何事情都不可接受。
@IBAction func doSomething()
@IBAction func doSomething(sender: UIButton)
@IBAction func doSomething(sender: UIButton, forEvent event: UIEvent)