如何在 swift 3 中使用 addTarget 方法

Posted

技术标签:

【中文标题】如何在 swift 3 中使用 addTarget 方法【英文标题】:How to use addTarget method in swift 3 【发布时间】:2017-01-29 18:46:00 【问题描述】:

这是我的button 对象

    let loginRegisterButton:UIButton = 
    let button = UIButton(type: .system)
    button.backgroundColor = UIColor(r: 50 , g: 80, b: 130)
    button.setTitle("Register", for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitleColor(.white, for: .normal)
    button.addTarget(self, action:#selector(handleRegister), for: .touchUpInside)
    return button
()

这是我的功能

    func handleRegister()

    FIRAuth.auth()?.createUser(withEmail: email, password: password,completion:  (user, error) in

        if error != nil
         print("Error Occured")

        else
        print("Successfully Authenticated")
    )        

我得到编译错误,如果 addTarget 删除它编译成功

【问题讨论】:

试试这个button.addTarget(self, action:#selector(handleRegister()), for: .touchUpInside) handleRegister 动作在同一个控制器中?你也没有设置UIButton的框架。 是的,我确实有另一个用于约束的函数 func constraints() loginRegisterButton.centerXAnchor.constraint(equalTo: inputview.centerXAnchor).isActive = true loginRegisterButton.topAnchor.constraint(equalTo: inputview. bottomAnchor, 常量:12).isActive = true loginRegisterButton.widthAnchor.constraint(equalTo: inputview.widthAnchor).isActive = true loginRegisterButton.heightAnchor.constraint(equalToConstant: 30).isActive = true @Ninja13 那么问题可能是您的按钮约束尝试设置一次框架并检查它是否正常工作。 我改变了这样的代码,它工作很懒 var loginRegisterButton:UIButton = let button = UIButton(type: .system) button.backgroundColor = UIColor(r: 50 , g: 80, b: 130 ) button.setTitle("Register", for: .normal) button.translatesAutoresizingMaskIntoConstraints = false button.setTitleColor(.white, for: .normal) button.addTarget(self, action:#selector(handleRegister), for: .touchUpInside)返回按钮 () 【参考方案1】:

是的,如果没有参数就不要加“()”

button.addTarget(self, action:#selector(handleRegister), for: .touchUpInside). 

如果你想得到发件人

button.addTarget(self, action:#selector(handleRegister(_:)), for: .touchUpInside). 

func handleRegister(sender: UIButton)
   //...

编辑:

button.addTarget(self, action:#selector(handleRegister(_:)), for: .touchUpInside)

不再起作用,您需要将选择器中的_替换为您在函数头中使用的变量名,在这种情况下它将是sender,因此工作代码变为:

button.addTarget(self, action:#selector(handleRegister(sender:)), for: .touchUpInside)

【讨论】:

好吧,这真的很容易.. 但是如何添加值示例.. button.addTarget(self, action:#selector(handleRegister(str: "Hello")), for: .touchUpInside) 您不能在选择器中设置参数。动作取决于目标的来源。如果要获取按钮的字符串,请在 handleRegister(sender: UIButton) 中从发送方获取当前标题 解决方法之一是将参数设置为按钮的辅助功能元素。但不确定这是否被 App Store 接受,因为我只尝试过企业应用程序。【参考方案2】:

用 Swift 4 试试这个

buttonSection.addTarget(self, action: #selector(actionWithParam(_:)), for: .touchUpInside)
@objc func actionWithParam(sender: UIButton)
    //...


buttonSection.addTarget(self, action: #selector(actionWithoutParam), for: .touchUpInside)
@objc func actionWithoutParam()
    //...

【讨论】:

不是一个大问题,但是如果不暴露给@objc,是否仍然没有办法做到这一点? 作为 Apple 官方文档 (developer.apple.com/documentation/swift/…),您需要使用 @objc 来调用您的 Selector 方法,没有其他“纯 swift”使用选择器的方式。【参考方案3】:

试试这个

button.addTarget(self, action:#selector(handleRegister()), for: .touchUpInside). 

只需在方法名称后面加上括号。

您也可以参考链接:Value of type 'CustomButton' has no member 'touchDown'

【讨论】:

其实不要加括号【参考方案4】:
  let button: UIButton = UIButton()
    button.setImage(UIImage(named:"imagename"), for: .normal)
    button.addTarget(self, action:#selector(YourClassName.backAction(_sender:)), for: .touchUpInside)

    button.frame = CGRect.init(x: 5, y: 100, width: 45, height: 45)
    view.addSubview(button)

    @objc public func backAction(_sender: UIButton) 

    

【讨论】:

【参考方案5】:

用 swift 3 试试

cell.TaxToolTips.tag = indexPath.row
        cell.TaxToolTips.addTarget(self, action: #selector(InheritanceTaxViewController.displayToolTipDetails(_:)), for:.touchUpInside)


 @objc func displayToolTipDetails(_ sender : UIButton) 
        print(sender.tag)
        let tooltipString = TaxToolTipsArray[sender.tag]
        self.displayMyAlertMessage(userMessage: tooltipString, status: 202)    

【讨论】:

【参考方案6】:

在 swift 3 中使用这个 -

object?.addTarget(objectWhichHasMethod, action: #selector(classWhichHasMethod.yourMethod), for: someUIControlEvents)

例如(来自我的代码)-

self.datePicker?.addTarget(self, action:#selector(InfoTableViewCell.datePickerValueChanged), for: .valueChanged)

如果您希望发送者作为参数,只需在方法名称后加上:

【讨论】:

【参考方案7】:

用 Swift 3 试试这个

button.addTarget(self, action:#selector(ClassName.handleRegister(sender:)), for: .touchUpInside)

祝你好运!

【讨论】:

【参考方案8】:

海报从 9 月 21 日开始的第二条评论是当场的。对于那些稍后可能会遇到与海报相同问题的人,这里有一个简短的解释。记住其他答案很好,但不要解决此代码遇到的常见问题。

在 Swift 中,使用 let 关键字进行的声明是常量。当然,如果要向数组中添加项,则数组不能声明为常量,但分段控件应该没问题,对吧?!如果您在其声明中引用完整的分段控件,则不会。

引用对象(在本例中为 UISegmentedControl,但 UIButton 也会发生这种情况)在其声明中当您说 .addTarget 并让目标为 self 时,事情碰撞。为什么?因为self 正在被定义中。但我们确实想将行为定义为对象的一部分...将其lazily 声明为带有var 的变量。 lazy 使编译器误以为 self 定义明确——它使编译器在声明时不再关心。延迟声明的变量在第一次被调用之前不会被设置。所以在这种情况下,lazy 让您在设置对象时毫无问题地使用self 的概念,然后当您的对象获得.touchUpInside.valueChanged 或您的第三个参数在您的@987654337 中时@, THEN 它调用了self 的概念,此时它已经完全建立并且完全准备好成为一个有效的目标。所以它让你在声明你的变量时变得懒惰。在这种情况下,我认为他们可以给我们一个像 necessary 这样的关键字,但它通常被视为一种懒惰、草率的做法,你不想在你的代码中使用它,尽管它可能在这种情况。它是什么

Swift 中没有lazy let(常量没有lazy)。

这里是Apple documentation on lazy。

这里是Apple on variables and constants。在Declarations 下的语言参考中还有更多内容。

【讨论】:

【参考方案9】:

代替

let loginRegisterButton:UIButton = 
//...  ()

试试:

lazy var loginRegisterButton:UIButton = 
//...  ()

这应该可以修复编译错误!!!

【讨论】:

【参考方案10】:

来自 Apple 文档的演示。 https://developer.apple.com/documentation/swift/using_objective-c_runtime_features_in_swift

import UIKit
class MyViewController: UIViewController 
    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))

    override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) 
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        // without parameter style
        let action = #selector(MyViewController.tappedButton)
        // with parameter style
        // #selector(MyViewController.tappedButton(_:))
        myButton.addTarget(self, action: action, forControlEvents: .touchUpInside)
    

    @objc func tappedButton(_ sender: UIButton?) 
        print("tapped button")
    

    required init?(coder: NSCoder) 
        super.init(coder: coder)
    

【讨论】:

以上是关于如何在 swift 3 中使用 addTarget 方法的主要内容,如果未能解决你的问题,请参考以下文章

iOS:在 Swift 中重新创建 addTarget() 的最佳实践?

Swift4 - UIButton 在 UIView 中使用 addTarget 时出错

UIButton 的 Swift addTarget 在 UIView 中不起作用

Swift addTarget中的Selector

Swift:UIScrollView 和 UIControl - addTarget | addGestureRecognizer - 没有按预期工作

UIControl.appearance().addTarget 停止在 Swift 4 上工作