2016-11-09 5 views
2

スウィフトで引数を取るセレクタを書くためにどのように...(私は意図的にテーブルビューメソッドを残している)スウィフト2ではこれが機能するために使用3

import Foundation 
import UIKit 

private extension Selector { 
    static let didTapButton = #selector(TableVC.buttonTapped(_ :)) 

} 

class TableVC: UITableViewController{ 

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     let btnAccView:UIButton = UIButton(frame: CGRectMake(0, 0, 27, 27)) 
     btnAccView.addTarget(self, action: .didTapButton, forControlEvents: UIControlEvents.TouchUpInside) 
     btnAccView.tag = indexPath.row 
    } 


    func buttonTapped(sender: UIButton){ 
     print("button tapped at row \(sender.tag)") 
    } 

} 

スウィフト3では、これはエラーが発生します。 " TableVCにはメンバーbuttonTappedがありません "。

引数を取るセレクタを書くだけでいいです。 私は考えることができるあらゆる方法で構文を練習しようとしましたが、何も効果がありませんでした。あなたの助けをありがとう

+1

[この質問](http://stackoverflow.com/q/24814646/5513562)の答えによると、それはすることはできません完了しました。 –

+1

http://fuckingclosuresyntax.com/ http://fuckingswiftblocksyntax.com/ –

+0

記録のために、質問を重複としてマークし、元の質問を参照しないことは、誰にも全く役に立たないことです。それが複製の場合は元の場所はどこですか? – GED125

答えて

3

最初に、buttonTappedを修正して、最初の引数のラベルが表示されないようにする必要があります。それは次のようになりますように、内部の引数のラベルの前にアンダースコアを挿入します。

func buttonTapped(_ sender: UIButton) { 

する前に、そのメソッドのシグネチャはTableVC.buttonTapped(sender:)だった、そして今その署名がTableVC.buttonTapped(_:)になります。エクステンション内のアンダースコアとコロンの間のスペースを削除する必要があるかもしれませんが、それはそれ以降にはうまくいくはずです。

ここでSelectorの内線番号を使用する特別な理由はありますか?その拡張モデルは通常、通知名のようなものは簡単に間違えてしまうことがあり、トリッキーなバグの原因となります。 Swiftコンパイラは、どこに配置されていても自動的に#selectorの宣言を検証するので、コードに直接入れることができます。拡張は必要ありません。

1

コンパイラに関数のシグニチャの一部を推論させることで、悲しみを節約できます。あなたの場合は...

class TableVC: UIViewController { 
    func buttonTapped(sender: UIButton) { /*...*/ } 
} 

あなたはどちらかとTableVCクラスの外からそれを参照することができます

  • #selector(TableVC.buttonTapped(sender:))
  • #selector(TableVC.buttonTapped)

二作品を一つだけありますので、 buttonTappedの機能はTableVCです。したがって、コンパイラは完全なシグネチャを必要とせず、曖昧さを排除します。

TableVCのコードの中から、さらにステップを簡略化して#selector(buttonTapped)を使用してください。その時点でクラススコープにあり、クラスのメソッドを安全に推論できるからです。

(あなたのメソッドは、func buttonTapped(_ sender: UIButton)として宣言されている場合にのみ、あなたが作品を使用している#selector(TableVC.buttonTapped(_:))ラインご利用の場合には、senderパラメータは引数のラベルを持っているかどうかは問題ではありません - 。あなたはちょうど約一貫する必要がfunc宣言と#selector式の間です。)

そして、@Bobノートでは、Selectorの拡張は必要ありません。コンパイラはすでにセレクタを検証しているためです。ボタンアクションのためのセレクタを実装する方法以下の

0

用途:

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

    override init?(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
     let action = #selector(MyViewController.tappedButton) 
     myButton.addTarget(self, action: action, forControlEvents: .touchUpInside) 
    } 

    func tappedButton(sender: UIButton?) { 
     print("tapped button") 
    } 

    required init?(coder: NSCoder) { 
     super.init(coder: coder) 
    } 
} 
関連する問題