2017-01-02 9 views
1

これはよくある問題ですが、私自身は解決策を見つけることができませんでした。クラスに送信されたセレクタが認識されない

ここでのコードは次のとおりです。

class ButtonViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     view.addSubview(button) 
    } 

    func exmp(sender: UIButton) { 
     print("hello world") 
    } 

    let button: UIButton = { 
     let but = UIButton(frame: CGRect(x: 33, y: 33, width: 33, height: 33)) 
     but.setTitle("-", for: .normal) 
     but.titleLabel?.textColor = UIColor.white 
     but.layer.cornerRadius = 10 
     but.backgroundColor = UIColor.red 
     but.addTarget(ButtonViewController.self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown) 
     return but 
    } 
} 

問題: 赤いボタンが表示されますが、私はそれをクリックしたときに、私はエラー「クラスに送信された認識されないセレクター」を取得します。

ご協力いただきましてありがとうございます。ありがとう。

+0

アドオン '@ objc' FUNCをexmp'の前に(送信者:UIButton) ' – NSDmitry

+0

この動作するはずbut.addTarget(ButtonViewController.self、アクション:#selector(exmp :)、 for:.touchDown) –

+0

は、インターフェイスビルダーでこのボタンを定義するだけです(必要に応じて必要になるまで非表示にします)。 – Alexander

答えて

0

私はこの問題を2日間見てきました。右addTarget方法は次のようにする必要があります

but.addTarget(self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown) 

しかしである私のためのもう一つの問題が残っていました「コマンドによる信号に失敗しました:セグメンテーションフォールト:11」を。

私はviewDidLoad()メソッドでボタンを作成しようとしましたが、エラーはありませんでした。だから私はそれがボタンが作成されているかどうかで何かかもしれないと思った。そして私はの代わりにを怠けて、ボタンを作成中にを入れました。

まだ、初心者としては、私は本当に "layz var"が何であるか知りません。私が知っているのは、それが呼び出されたときにのみ、ボタンが作成されるということです。 誰かが私と初心者の周りに怠惰な瓶について啓蒙してくれればうれしいです。ありがとう。

最終解決

override func viewDidLoad() { 
    super.viewDidLoad() 

    view.addSubview(button) 
} 

func exmp(sender: UIButton) { 
    print("hello world") 
} 

lazy var button: UIButton = { 
    let but = UIButton(frame: CGRect(x: 33, y: 33, width: 33, height: 33)) 
    but.setTitle("-", for: .normal) 
    but.titleLabel?.textColor = UIColor.white 
    but.layer.cornerRadius = 10 
    but.backgroundColor = UIColor.red 
    but.addTarget(self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown) 
    return but 
}() 
+0

遅延血管は、初めて使用されるときに初期化されます。ここで重要な理由は、クラスが初期化されるまで、プロパティの初期化に 'self'が使用できないということです。あなたのvarを怠惰にすることで、そのプロパティの初回使用時までそのプロパティの初期化を延期することによって、その制限を回避できます。このとき、オブジェクトは初期化され、「自己」が使用されます。 – vacawama

5

間違ったターゲットを設定したため、認識できないセレクターがクラスに送信されました。 ターゲットはselfないButtonViewController.self次のようになります。

but.addTarget(self, action: #selector(ButtonViewController.exmp(sender:)), for: .touchDown) 

あなた#selector作品が、スウィフト3のためにあなたがセレクタ#selector(exmp(_:))を作るfunc exmp(_ sender: UIButton) {などのアクションを記述する必要があります。注:exmpを書き換えるかどうかにかかわらず、セレクタを簡略化して#selector(exmp)にすることができます。

+2

私はこれに関してSwiftにバグを提出しました。コンパイラは、一方では '#selector'構文で助けてはいけませんが、もう一方では間違ったターゲットを設定させるべきです。 「認識できないセレクタ」はデッドレターでなければなりません! – matt

+0

良い点@matt。 – vacawama

+1

ここでは記録のためだけです:https://bugs.swift.org/browse/SR-1906 – matt

関連する問題