2016-12-20 4 views
0

ボタンタッチで呼び出しを行うアクションを設定しようとしています。 ボタンIBに作成し、メインクラスで必要な操作を設定しようとしています。Swift:内部クラスのボタンターゲットを追加する

設定が完了したら、ボタンに触れても何も起こりません。私は、のターゲットまたはのアクションセレクタに問題があると推測します。この場合、私はどちらを使うべきですか?ありがとう!例については

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

UIViewクラスでボタンアクションを作成するだけです。このメソッドでは、メインコントローラクラスで定義するブロックを呼び出すことができます。 – Amanpreet

+0

あなたのボタンの '@ IBAction'を' setPhone() 'メソッドにフックしましたか? – sargeras

+0

@Amanpreetはオプションのように聞こえるが、その関数(呼び出し)に値を渡す必要がある。何とかそれを私のボタンに関連付けるのだろうか? –

答えて

1

を、あなたはPhoneCallSetterの新しいインスタンスを作成し、そのメソッドinitialize(_:phoneNumber:)を呼び出すことができますが、どこでも、インスタンスを保持していません。

オブジェクトをアクションターゲットにするには、オブジェクトを強い参照でどこかに保持する必要があります。 UIButton(または他のいずれかのUIControl)は、弱い参照でターゲットオブジェクトを保持するだけです。

つまり、メソッドinitialize(_:phoneNumber:)の実行が終了すると、PhoneCallSetterのインスタンスが解放されます。すでにリリースされたインスタンスに送信されたアクションメソッドは、自動的に無視されます。

したがって、次のような、強い参照してインスタンスを維持する必要があります。

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

しかし、あなたは行動目標としてプライベートクラスを作るあえて理由を私は理解していません。非標準的な方法では、非標準的な作業を強いられるので、避けてください。内部クラスで

+0

ありがとう!これがまさに理由でした。また、私はあなたのアドバイスを取って、コードを書き直していますが、実際には見えませんでした... –

0

:Controllerクラスで

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

は、あなたがしたいブロックを使用しています。

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

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

注:ここでは VEWは、UIViewクラスのオブジェクトであるあなたがボタンを押したときにのみ呼び出されます。

0

問題はあなたのsetPhone()の機能のように私に見えます。この関数は、PhoneCallSetterクラスの新しいインスタンスを作成し、それをinitializeメソッドと呼びますが、そのオブジェクトでは何もしません。あなたのストーリーボードにUIViewオブジェクトを作成し、そのクラスをPhoneCallSetter(おそらく最高)に変更するか、コード内のビュー階層にPhoneCallSetterオブジェクトを追加する必要があります。 (しかし、それは少しトリッキーです、それに制約を、設定を意味します。)あなたのsetPhone()方法で

0

あなたの目標は、入れ子にする必要があります(継承)

button.addTarget(ビューPhoneCallSetter、アクション:。#selector(PhoneCallSetter.call)、forControlEvents:UIControlEvents.TouchUpInside)このような

何か。

0

てみてください、ここでボタンのアウトレットの名前を変更する:あなたは、両方で同じボタンの名前を持っているよう

@IBOutlet weak var button: UIButton! 

あなたの関数

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

は、押された実際のボタンを認識することができません場所。

関連する問題