如何在 swift 中为自定义按钮操作制作地球仪方法

How to make globe method for custom button action in swift

我有一个登录屏幕,其中两个字段是密码和电子邮件文本字段。 我用堆栈视图添加了两个文本字段。添加文本字段后,我需要添加密码锁定按钮。单击密码锁定按钮后,用户可以看到密码。我从库中取出按钮并尝试添加文本字段,但是由于 stackview,它总是设置为 stackview 的第三个元素。所以我无法添加。 所以我决定添加文本字段的扩展名。所以我在实用程序 class 中成功添加了按钮, 但无法使用选择器添加操作。它显示错误

Value of type 'UIViewController' has no member 'passwordAction'

我的添加按钮代码是

extension UITextField {

func passwordButton(vc:UIViewController){
    let paddingView = UIView(frame: CGRect(x: 25, y: 25, width: 24, height: 17))
    let passwordButton = UIButton(frame: CGRect(x: 0, y: 0, width: 24, height: 17))
    passwordButton.setImage(UIImage(named: "show_password"), for: .normal)
    passwordButton.addTarget(vc, action: #selector(vc.passwordAction), for: .touchUpInside)
    paddingView.addSubview(passwordButton)
    self.addSubview(paddingView)
}
}
class Loginviewcontroller{
   passwordTextField.passwordButton(vc: self)
 func passwordAction(){
  print("action")
 }
 }

我正在从登录控制器调用此方法。

所以我有两个问题:-

  1. 当两个文本字段附加到 stackview 时,我们不能将按钮放在带有情节提要的文本字段上吗?
  2. 如何制作 globle 方法来添加按钮并添加可以在 uiviewcontroller 中访问的操作?

错误是不言自明的,您将 passwordAction 方法添加到 Loginviewcontroller 但在 func passwordButton 中您将 UIViewController 作为参数。因此,即使您将 Loginviewcontroller 的实例传递给 passwordButton 函数调用,在函数范围内 vc 也只是另一个 UIViewController 并且显然所有 UIViewController 都是没有名为 passwordAction.

的方法

正如你所说,你想制作全局方法来添加按钮并添加可以在 uiviewcontroller 中访问的操作你可以按照下面的方法

第 1 步:声明一个协议

@objc protocol SecureTextProtocol where Self: UIViewController {
    func passwordAction()
}

第 2 步: 更新您的 passwordButton 方法以采用 SecureTextProtocol 而不是普通的 UIViewController

extension UITextField {

    func passwordButton(vc:SecureTextProtocol){
        let paddingView = UIView(frame: CGRect(x: 25, y: 25, width: 24, height: 17))
        let passwordButton = UIButton(frame: CGRect(x: 0, y: 0, width: 24, height: 17))
        passwordButton.setImage(UIImage(named: "show_password"), for: .normal)
        passwordButton.addTarget(vc, action: #selector(vc.passwordAction), for: .touchUpInside)
        paddingView.addSubview(passwordButton)
        self.addSubview(paddingView)
    }
}

第 3 步: 让您的 ViewController 想要获得按钮操作以确认 SecureTextProtocol 协议

class Loginviewcontroller: UIViewController, SecureTextProtocol {
    passwordTextField.passwordButton(vc: self)

    func passwordAction(){
        print("action")
    }
}

这应该可以完成工作

你总是可以用简单的代码解决这个问题,我就是这样做的。

    extension UITextField {
func setPasswordToggleImage(_ button: UIButton) {
    if(isSecureTextEntry){
        button.setImage(UIImage(named: "ic_password_visible"), for: .normal)
    }else{
        button.setImage(UIImage(named: "ic_password_invisible"), for: .normal)

    }
}

func enablePasswordToggle(){
    let button = UIButton(type: .custom)
    setPasswordToggleImage(button)
    button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
    button.frame = CGRect(x: CGFloat(self.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25))
    button.addTarget(self, action: #selector(self.togglePasswordView), for: .touchUpInside)
    self.rightView = button
    self.rightViewMode = .always
}
@objc func togglePasswordView(_ sender: Any) {
    self.isSecureTextEntry = !self.isSecureTextEntry
    setPasswordToggleImage(sender as! UIButton)
}
}

然后在 viewcontroller 的 viewdidload 上调用故事板上的函数

override func viewDidLoad() {
             super.viewDidLoad()
             txtPassword.enablePasswordToggle()
             txtConfirmPassword.enablePasswordToggle()
         }