How to call a UISwitch touch without using IBaction/InterfaceBuilder - ios

I am trying to call a function whenever my UISwitch is tapped without using an #ib action but am having trouble finding the proper way to do this nothing is seeming to work no matter how i try to call it. I am using everything through code and not storyboard so using an ib property isn't really an option i am trying to use at going about this
I am using this but keep getting the error
terminating with uncaught exception of type NSException
func gameSwitchTapped(){
print("touched")
if gameMuteSwitch.isOn == true {
gameview.saveData.set(false, forKey: gameview.gameMuteKey)
} else {
gameview.saveData.set(true, forKey: gameview.gameMuteKey)}
}
And, elsewhere:
gameMuteSwitch.addTarget(self, action: Selector(("gameSwitchTapped")), for: UIControlEvents.valueChanged)

I think this should do it:
mySwitch.addTarget(self, action: #selector(self.switchChanged(sender:)), forControlEvents: UIControlEvents.ValueChanged)
func switchChanged(sender: UISwitch) {
let value = mySwitch.on
// Do something
}

In Objective C:
[mySwitch addTarget:self action:#selector(action:) forControlEvents:UIControlEventValueChanged];

Related

Adding an observer to a UISwitch within a custom tableview cell

This is a follow on from a previous question I have asked but I feel I am missing something very simple and its driving me up the wall!
I have a custom tableview cell which contains a switch and I need to trigger a function each time it's value is changed. I've tried using .addTarget but it never seems to trigger the function so maybe my selector syntax is incorrect.
I create the switch programatically within the tableview cell like this:
let thisSwitch: UISwitch = {
let thisSwitch = UISwitch()
thisSwitch.isOn = false
thisSwitch.translatesAutoresizingMaskIntoConstraints = false
thisSwitch.addTarget(self, action: Selector("switchTriggered:"), for: .valueChanged)
return thisSwitch
}()
Then directly below that I have my function:
func switchTriggered(sender: AnyObject) {
print("SWITCH TRIGGERED")
let sentSwitch = sender as! UISwitch
privateExercise.switchState = sentSwitch.isOn
}
It shows an error message stating " No method declared with Objective-C selector 'switchTriggered:' ". What am I missing here? Any help would be much appreciated!
The selector syntax should be
thisSwitch.addTarget(self, action: #selector(switchTriggered), for: .valueChanged)
Also keep the parameter as UISwitch type itself in order to avoid casting in function
func switchTriggered(sentSwitch: UISwitch) {
print("SWITCH TRIGGERED")
privateExercise.switchState = sentSwitch.isOn
}

UISwitch value changed action: unrecognized selector sent to class

I am using Xcode 8.1 and swift 3.0. and I am creating a UISwitch programmatically, and the code is:
let preconnectedSwitch = UISwitch()
preconnectedSwitch.isOn = true
preconnectedSwitch.addTarget(self, action: #selector(switchValueDidChange), for: .valueChanged)
func switchValueDidChange() {
print("file:- \(#file) , fucntion:- \(#function), line:- \(#line) ")
// print("\(sender.isOn)")
// UserDefaults.standard.set(true, forKey: Constant.USER_DEFAULT_IS_CONNECTED)
}
But when I change UISwitch value then application crash with this error
I think the problem is that this is a Swift function, not an Objective-C function. Add the #IBAction tag to your function. That will tell the compiler to create an Objective-C function.

Selector for different ViewController

Inside an extension for UIButton, I create a button and add its target.
extension UIButton {
convenience init(target: AnyObject) {
self.init(type: .system)
self.addTarget(target, action: Selector("setLang:"), for: .touchUpInside)
}
}
In ViewController, when using the custom init function to create the button, as target, I pass self.
This worked fine before upgrading my code to Swift 3. Now, however, I receive an error when tapping the button saying:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MyApp.ViewController setLang:]: unrecognized selector sent to instance xxx
Inside ViewController there is the following function declared that is supposed to be called:
func setLang(button: UIButton) {
//...
}
Any ideas?
Thanks in advance!
i found that solution from apple developer Forums. This may help you.
selectionButton.addTarget(self, action: #selector(SingleQuestionViewController.selected(_:)), for: .touchUpInside)
// try like this , i hope it will work for you.
self.addTarget(target, action: NSSelectorFromString("setLang:"), for: .touchUpInside)
Found the problem. Instead of declaring the function like I did before, I need to do it the following way:
func setLang(_ button: UIButton) {
//...
}
Hope this helps other peeps.

Having trouble targeting a DesignableView in a UITableViewCell upon tapping it in order to change

and thanks in advance for taking the time to help.
Inside my CellForRowAtIndexPath, I have the following line:
cell.timeView.addTarget(self, action: "ButtonDidPress:", forControlEvents: UIControlEvents.TouchUpInside)
and my selector function is:
func ButtonDidPress (sender: DesignableView!){
let view:DesignableView = sender
cell.timeView.shadowColor = UIColor.yellowColor()
table.reloadData()
}
and the error i get is:
unrecognized selector sent to instance
I'm thinking that perhaps one can't send a View as a selector (am I using the correct terminology?), but how else can I target that particular view in that cell?
UPDATE:
I also tried using gestureRecognizer instead:
var tap = UIGestureRecognizer(target: self, action: Selector( "viewDidTap:"))
cell.timeView.addGestureRecognizer(tap)
and
func viewDidTap (sender: DesignableView!){
but I got the same error here.
Thanks!
There's a couple of strange things happening in your code. It seems you want to change the shadowColor property of timeView when a user touch it, right?
Two possible solutions are:
(This one is IMO the better one) Change DesignableView to inherit from UIButton. Then you can set:
timeView.addTarget(self, action: "ButtonDidPress:", forControlEvents: .TouchUpInside). Make sure you set it just once for each cell. Otherwise you will get multiple calls on one tap.
Use UITapGestureRecognizer, but you should put it in your UITableViewCell subclass, not to the view controller. Also, the sender in viewDidTap is not the view itself, but the recognizer. So the method will go like this:
func viewDidTap(sender: UITapGestureRecognizer) {
let location = sender.locationInView(sender.view)
if timeView.hitTest(location, withEvent: nil) == timeView {
timeView.shadowColor = UIColor.yellowColor()
// table.reloadData() - you don't need to reload the table
}
}

How to call selector from switch only when change to state ON in Swift?

I need call a function with selector when change switch, but only when I set switch to On state:
cell.switchMy.addTarget(self, action: "openView", forControlEvents: UIControlEvents.ValueChanged)
func openView(){
var cell:CustomCell = self.tableView.dequeueReusableCellWithIdentifier("cell5") as CustomCell
if(cell.switchMy.on == true){
println("ON")
self.performSegueWithIdentifier("segueUnl", sender: self)
}
}
If I use this code, always call the function, but I 'm controlling if the switch state is ON... How can this correctly?
This is (nearly) the right way to do this. You can't have a method be called only when the switch state is on.
But you don't need to retrieve the cell from the openView method. The sender will be passed by the caller:
cell.switchMy.addTarget(self, action: "openView:", forControlEvents: UIControlEvents.ValueChanged)
func openView(sender: UISwitch){
if(sender.on) {
println("ON")
self.performSegueWithIdentifier("segueUnl", sender: self)
}
}
Be careful: the selector used in addTarget needs to be changed from openView to openView:

Resources