web-dev-qa-db-ja.com

Swiftのセレクターに引数を渡す

私はプログラムでUITapGestureRecognizerをビューの1つに追加しています。

let gesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(modelObj:myModelObj)))

self.imageView.addGestureRecognizer(gesture)

func handleTap(modelObj: Model) {
  // Doing stuff with model object here
}

最初に遭遇した問題は、「 '#selector'の引数が '@Objc'のメソッド、プロパティ、または初期化子を参照していない」ことでした。

クールなので、@ objcをhandleTapシグネチャに追加しました。

@objc func handleTap(modelObj: Model) {
  // Doing stuff with model object here
}

現在、「パラメータのタイプをObjective-Cで表すことができないため、メソッドに@objcをマークできません」というエラーが表示されています。

これは、建物の地図の画像にすぎず、いくつかのピン画像は関心のある場所の位置を示しています。ユーザーがこれらのピンのいずれかをタップすると、タップした関心のあるポイントを知りたいのですが、これらの関心のあるポイントを記述するモデルオブジェクトがあります。このモデルオブジェクトを使用して、ピンイメージにマップ上の座標を与えるため、ジェスチャハンドラーにオブジェクトを送信するだけで簡単だと思いました。

48
mike

いくつかのことを誤解しているようです。

target/action を使用する場合、関数シグネチャには特定の形式が必要です…

func doSomething(sender: Any)

または

func doSomething(sender: Any, forEvent event: UIEvent)

どこ…

senderパラメーターは、アクションメッセージを送信するコントロールオブジェクトです。

あなたの場合、送信者はUITapGestureRecognizerです

また、#selector()にはfunc署名が含まれている必要があり、渡されたパラメーターは含まれていません。だから…

func handleTap(sender: UIGestureRecognizer) {

}

あなたが持っている必要があります...

let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))

FuncとジェスチャがView Controller内にあり、そのmodelObjがプロパティ/ ivarであると仮定すると、ジェスチャ認識でそれを渡す必要はありません。handleTapで参照できます。

62
Ashley Mills

ステップ1:送信者のカスタムオブジェクトを作成します。

ステップ2:送信者のカスタムオブジェクトで変更したいプロパティを追加します

手順3:受信関数の送信者をカスタムオブジェクトに型キャストし、それらのプロパティにアクセスする

例:ボタンをクリックすると、文字列またはカスタムオブジェクトを送信する場合

ステップ1:作成

class CustomButton : UIButton {

    var name : String = ""
    var customObject : Any? = nil
    var customObject2 : Any? = nil

    convenience init(name: String, object: Any) {
        self.init()
        self.name = name
        self.customObject = object
    }
}

ステップ2-a:次のように、カスタムクラスでそのボタンのIBOutletを作成します

@IBOutlet weak var btnFullRemote: CustomButton!

ステップ2-b:ストーリーボードでもカスタムクラスを設定します

enter image description here

ステップ3:送信者のカスタムオブジェクトで変更するプロパティを追加します

btnFullRemote.name = "Nik"
btnFullRemote.customObject = customObject
btnFullRemote.customObject2 = customObject2
btnFullRemote.addTarget(self, action: #selector(self.btnFullRemote(_:)), for: .touchUpInside)

ステップ4:受信関数の送信者をカスタムオブジェクトに型キャストし、それらのプロパティにアクセスする

@objc public func btnFullRemote(_ sender: Any) {

var name : String = (sender as! CustomButton).name as? String

var customObject : customObject = (sender as! CustomButton).customObject as? customObject

var customObject2 : customObject2 = (sender as! CustomButton).customObject2 as? customObject2

}
16
Ninad Kambli