Xcode 在Swift中以编程方式设置操作侦听器

Xcode 在Swift中以编程方式设置操作侦听器,xcode,swift,Xcode,Swift,我看到一些示例代码将相同的OnClick事件分配给Android中的所有按钮(即使它们执行完全不同的操作)。用斯威夫特怎么办 Android示例: @Override public void onCreate(Bundle savedInstanceState) { button1.setOnClickListener(onClickListener); button2.setOnClickListener(onClickListener); b

我看到一些示例代码将相同的OnClick事件分配给Android中的所有按钮(即使它们执行完全不同的操作)。用斯威夫特怎么办

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; 
         } 

   } 
}; 

注意:我不想以编程方式创建按钮

在iOS上,您没有设置侦听器;将目标(对象)和操作(iOS术语中的方法签名,“选择器”)添加到
UIControl
(其中
UIButton
是的子类):

第一个参数是目标对象,在本例中为
self
。该操作是一个选择器(方法签名),基本上有两个选项(稍后将详细介绍)。这是一个特定于
UIControl
-
的位。触碰内部
通常用于点击按钮

现在,行动。这是以下格式之一的方法(名称由您选择):

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
是实例变量)

代替大开关语句的这一个方法考虑使用每个按钮的单独方法。根据您的特定用例,任何一种方法都可能更好:

func button1Clicked() {
  // do something
}

func button2Clicked() {
  // do something
}

func button3Clicked() {
  // do something
}
在这里,我甚至没有使用
sender
参数,因为我不需要它

注意:您可以在故事板或nib文件中添加目标和操作,而不是以编程方式添加目标和操作。为了公开您在函数前面放置的
iAction
操作,例如:

@IBAction func button1Clicked() {
  // do something
}

Swift 4.*

button.addTarget(self, action: #selector(didButtonClick), for: .touchUpInside)
该按钮将触发此功能:

@objc func didButtonClick(_ sender: UIButton) {
    // your code goes here
}

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")                  
}

可能重复的不。。。我需要将同一个侦听器添加到多个按钮。。。这不是重复的。在指向相同操作的每个按钮上调用addTarget方法?UIcontrol有一个方法-addTarget,可以指向相同的“侦听器”。但是从您的代码判断,为什么不使用4个侦听器而不是一个确定按下了哪个按钮的侦听器?@cream corn因为您可能有一个动态表结构,其中的按钮可以使用行索引进行映射。现在应该将其写为#选择器(buttonClicked(sender:))或使用#选择器(buttonClicked(:))btnal.addTarget(self,action:#选择器(buttonClicked(:)),for:.touchUpInside)然后更改您的函数,如func buttonClicked(uuSender:UIButton){……}如果我为所有按钮设置了相同的函数,如何检查单击了哪个按钮?要检查单击了哪个按钮,请在创建按钮时设置不同的标记。button.tag=1(或2或3)。然后使用:switch sender.tag{case 1:。。。
buttonA.setOnClickListener {
  print("button A clicked")                  
}