0

ok i'm trying to build a simple UISlider in swift and i always get the same error when i run my code, it's a sigbrt error and it gives me this error:

2015-06-03 22:36:52.659 myslider[2780:224039] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[myslider.ViewController sliderValueChanged:]: unrecognized selector sent to instance 0x7f92f1e25340' * First throw call stack:

here's the code:

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var ValueLabel: UILabel!

    var slider: UISlider!



    override func viewDidLoad() {
        super.viewDidLoad()


  slider = UISlider(frame: CGRectMake(100, 100,  200,  23))
        slider.minimumValue = 0
        slider.maximumValue = 100
        view.addSubview(slider)

        slider.center = view.center

        slider.value = slider.maximumValue / 3.0

        slider.addTarget(self, action: "sliderValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
        slider.continuous = false
        salueDidChange(slider)
        ChangeColor()
        thumbImage()

    }
    func salueDidChange(sender: UISlider){
        ValueLabel.text = "\(sender.value)"
    }
    func ChangeColor(){
        slider.maximumTrackTintColor = UIColor.redColor()
        slider.minimumTrackTintColor = UIColor.greenColor()


    }
    func thumbImage(){
        slider.setThumbImage(UIImage(named: "thumbNormal"), forState: UIControlState.Normal)

        slider.setThumbImage(UIImage(named: "thumbHighlighted"), forState: UIControlState.Highlighted)

    }

}
Jonathan Meguira
  • 1,860
  • 2
  • 12
  • 15
  • 2
    Your action is "sliderValueChanged" but your function is called "salueDidChange". It's just a typo. – shim Jun 03 '15 at 21:01
  • I tried changing the name of the method and adding the @IBAction at the beginning of the function and it didi't change nothing i'm clueless – Jonathan Meguira Jun 04 '15 at 06:21
  • You are adding the target programmatically; The @IBAction is for connecting the method in the storyboard. Make sure your function name is exactly the same as the action you're trying to connect it to. Show your updated code and error message if you're still stuck. – shim Jun 04 '15 at 18:44

3 Answers3

2

With slider.addTarget(self, action: "sliderValueChanged:", forControlEvents: UIControlEvents.ValueChanged) you're telling Swift to call the method sliderValueChanged: on your ViewController, but there is no such method in your ViewController. That's what the error is telling you. Most likely you wrote salueDidChange for the same purpose so you should rename salueDidChange to sliderValueChanged and add @IBAction.

If that doesn't work, try connecting the event handler from your storyboard:

  • Remove the slider.addTarget line of code.
  • Right click your slider in your storyboard. See if there's an event handler hooked up for the value changed event. If so remove it using the little x.
  • Ctrl-drag from your slider to your sliderValueChanged method to hook it up again.
Steven Van Impe
  • 1,153
  • 8
  • 15
2

The error is telling you exactly what's wrong. You're creating a UISlider in code. You set up it's target like this:

slider.addTarget(
  self, 
  action: "sliderValueChanged:", 
  forControlEvents: UIControlEvents.ValueChanged)

So when you change the value of your slider, the method is going to try to call a method "sliderValueChanged:" in your view controller. That method needs to take 1 parameter, a sender:

@IBAction func sliderValueChanged(sender: AnyObject)
{
  //Do something with the new slider value.
}

The type of sender can also be type UISlider.

If you don't have a method with that signature in your view controller, you will crash when you change the slider value, just like you say you are.

EDIT:

As others have pointed out in their comments/answers, it looks like your target method is the misnamed method salueDidChange. You should rename it.

It's also a good idea to put the @IBAction tag on methods that will be called from controls. You must do that if you're going to define the control and connect it's action in Interface Builder (which is a good idea, rather than doing it in code.)

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • I tried changing the name of the method and adding the @IBAction at the beginning of the function and it didi't change nothing i'm clueless – Jonathan Meguira Jun 04 '15 at 06:21
  • So stop trying to add the slider in code. Add it in IB and control-drag from the slider to the view controller to connect the action. – Duncan C Jun 04 '15 at 10:43
  • 1
    Add an edit to the bottom of your question showing your new code so we can help you debug it. – Duncan C Jun 04 '15 at 17:52
2

Jonathan, I had a similar frustrating experience with unrecognized selector and UISlider. Others have already said salueDidChange is a typo but it isn't the only issue. The syntax for selector has been a source of confusion for newcomers (like me) as Swift evolved.

The correct syntax for selector is explained in a nut shell in this answer to an unrelated problem.

“Using #selector will check your code at compile time to make sure the method you want to call actually exists. Even better, if the method doesn’t exist, you’ll get a compile error: Xcode will refuse to build your app, thus banishing to oblivion another possible source of bugs.”

Your question along with answers here helped me reach a working solution in Swift 3 below.

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var ValueLabel: UILabel!

var slider: UISlider!

override func viewDidLoad() {
    super.viewDidLoad()

    slider = UISlider(frame: CGRect(x: 100, y: 100, width: 200, height: 23))
    slider.minimumValue = 0
    slider.maximumValue = 100
    view.addSubview(slider)

    slider.center = view.center

    slider.value = slider.maximumValue / 3.0

    slider.addTarget(self, action: #selector(sliderValueChanged), for: UIControlEvents.valueChanged)
    slider.isContinuous = false

    changeColor()
    thumbImage()
    }


func sliderValueChanged(sender: UISlider){
    print(sender.value)

//        ValueLabel.text = "\(sender.value)" // Note: not included in this test!!!

    }

func changeColor(){
    slider.maximumTrackTintColor = UIColor.red
    slider.minimumTrackTintColor = UIColor.green
    }

func thumbImage(){
    slider.setThumbImage(UIImage(named: "thumbNormal"), for: UIControlState.normal)
    slider.setThumbImage(UIImage(named: "thumbHighlighted"), for: UIControlState.highlighted)
    }

}
Community
  • 1
  • 1
Greg
  • 1,750
  • 2
  • 29
  • 56