Swift:在内部类中添加按钮目标

时间:2016-12-20 12:47:51

标签: ios swift uibutton

我试图设置一个按钮触摸时调用的动作。我在 IB 中创建了按钮,在主类中我尝试设置所需的操作。

完成所有设置后,我触摸按钮,没有任何反应。我想 target 动作选择器存在问题:在这种情况下我应该使用?谢谢!

class View: UIView {

    private class PhoneCallSetter: UIResponder {

      private var phone: String!

      func initialize(button: UIButton!, phoneNumber: String!) {
        self.phone = phoneNumber

        button.addTarget(self, action: #selector(PhoneCallSetter.call), forControlEvents: UIControlEvents.TouchUpInside)
      }

      @objc func call() {
        if let phoneCallURL: NSURL = NSURL(string: "tel://\(phone)") {
            let application: UIApplication = UIApplication.sharedApplication()
            if (application.canOpenURL(phoneCallURL)) {
                application.openURL(phoneCallURL);
            }
        }
      }
   }

@IBOutlet weak var button: UIButton!

// somewhere down there I call
func setPhone() {
    PhoneCallSetter().initialize(button, phoneNumber: "123-456")
}}

5 个答案:

答案 0 :(得分:1)

setPhone()方法中,您创建了PhoneCallSetter的新实例,并调用其方法initialize(_:phoneNumber:),但您没有将实例保留在任何位置。

对于要成为动作目标的对象,需要将对象保留在具有强引用的某个位置。 UIButton(或任何其他UIControl)仅使用弱引用保存目标对象。

这意味着,一旦方法initialize(_:phoneNumber:)完成执行,就会释放PhoneCallSetter的实例。发送到已发布实例的操作方法可能会被静默忽略。

因此,您需要使用强引用保留实例,例如:

var phoneCallSetter: PhoneCallSetter?
func setPhone() {
    self.phoneCallSetter = PhoneCallSetter()
    self.phoneCallSetter!.initialize(button, phoneNumber: "123-456")
}

但我不明白为什么你敢把私人课作为行动目标。非标准的方式迫使你做出非标准的努力,你最好避免。

答案 1 :(得分:0)

例如:

class FV_OrderComplete: UIView {
   var block_OrderSubmit: (() -> ())!
    var block_checkPincode: ((String) -> ())!

    @IBAction func didActButtonOK(_ sender: AnyObject)
        {
            if block_OrderSubmit != nil{
                block_OrderSubmit()
            }

           if block_checkPincode != nil{
            block_checkPincode(txtField_Pincode.text!)
        }
    }
}

在Controller类中,使用您想要的块。它只会在您按下按钮时调用:

self.vew.block_OrderSubmit  =
            {
                ()in
               //write code
        }

      self.vew.block_checkPincode =
        {
            (str_Pincode: String) in
             //write code and use the passed data
        }

注意:这里 vew 是UIView类的对象。

答案 2 :(得分:0)

在我看来问题就是你的setPhone()功能。该函数创建了PhoneCallSetter类的新实例,然后调用它的初始化方法,但是你永远不会对该对象做任何事情。您应该在故事板中创建UIView对象并将其更改为PhoneCallSetter(可能是最好的),或者在代码中将ViewCallSetter对象添加到视图层次结构中。 (但这意味着要对它设置约束,这有点棘手。)

答案 3 :(得分:0)

内部类中的目标应该嵌套(继承)

button.addTarget(View.PhoneCallSetter,action:#selector(PhoneCallSetter.call),forControlEvents:UIControlEvents.TouchUpInside)

像这样的东西。

答案 4 :(得分:0)

尝试在此处更改按钮插座的名称:

@IBOutlet weak var button: UIButton!

你的功能

func initialize(button: UIButton!, phoneNumber: String!)

无法识别按下的实际按钮,因为两个地方的按钮名称相同。