26588


# Code

[code]

    var stepRatingView: AXRatingView = AXRatingView(frame: CGRectZero)
    
    stepRatingView.sizeToFit()
    stepRatingView.stepInterval = 1.0
    stepRatingView.addTarget(self, action: Selector(ratingChanged(stepRatingView)), forControlEvents: UIControlEvents.ValueChanged)
    self.secondView.addSubview(stepRatingView)
    
    func ratingChanged(sender: AXRatingView){
        print(stepRatingView.value)
        self.label.text =  String(sender.value)
    }
    
[/code]

# どうしたいのか

Amazonなどで見られる「★★★★★」の評価を、スライドで行おうと思い、  
コードをSwiftに読み替えています。

Objective-Cのコードではラベルの値が変化するのですが、  
Swiftに変換するとラベルの値が変化しません。

うまくaddTargetのactionが接続できていないのでしょうか。


CC BY-SA 3.0
2016-06-09T05:55:36.710
26578
2016-06-09T10:39:47.493
2016-06-09T07:12:07.417
5519
16765
question
swift xcode swift2 xcode7
addTargetでactionがうまく機能しない?


Selectorインスタンスの作り方が間違っています。

`Selector(ratingChanged(stepRatingView))`と言うのは、`Selector`のコンストラクターに、引数として`ratingChanged(stepRatingView)`と言う
**メソッドを呼び出した結果**
を渡しています。(従ってこの行が実行された時に`ratingChanged(_:)`が実行されているはずです。)`ratingChanged(_:)`の戻り値は`Void`ですので、結局`Selector()`と同じ結果になります。

`Selector`インスタンスをコンストラクターで作成する場合には、`Selector("Objective-
C形式のメソッド名")`の形を使います。あなたのコードだとこんな感じです。

[code]

        stepRatingView.addTarget(self, action: Selector("ratingChanged:"), forControlEvents: .ValueChanged)
    
[/code]

ただし、Xcode7.3以降をお使いでしたら、(Swift3への準備として)`#selector`構文を使われた方が良いでしょう。

短い書き方(同じクラス内のメソッドで、オーバーロードされていない場合)

[code]

        stepRatingView.addTarget(self, action: #selector(ratingChanged), forControlEvents: .ValueChanged)
    
[/code]

長い書き方(できるだけ曖昧になりにくい書き方)

[code]

        stepRatingView.addTarget(self, action: #selector(ViewController.ratingChanged(_:)), forControlEvents: .ValueChanged)
    
[/code]

(`ViewController`は、ご自分のview controllerクラス名に置き換えてください。)

`#selector`構文を使うとコンパイル時に指定されたメソッドが存在するかどうかのチェックをしてくれますので、「`addTarget(_:action:forControlEvent:)`は確かに実行されているのにactionメソッドが呼ばれない」と言ったミスを減らすことができます。お試しください。


CC BY-SA 3.0
2016-06-09T10:39:47.493
26588
2016-06-09T10:39:47.493
13972
26578
answer