iosswift3uibuttonselectoraddtarget

Assign 'action' dynamically in uibutton.addTarget


please bear with me, as I'm new to swift -4 weeks old-.

I've created the following 2 functions in fileA.swift

func custombttn(theSelector:Selector)-> UIButton{

        let bttn = UIButton(frame: CGRect(x:20, y:400, width:200, height:30))
            bttn.setTitle("tap this button", for: UIControlState.normal)
                bttn.backgroundColor = UIColor.black
                    bttn.setTitleColor(UIColor.magenta, for: UIControlState.normal)
    bttn.addTarget(bttn, action: theSelector, for: UIControlEvents.touchUpInside)

        return bttn

}

func customtxtfld() -> UITextField{

    let txtField = UITextField(frame: CGRect(x:20, y:360, width:200, height:30))

    txtField.borderStyle = UITextBorderStyle.roundedRect
        txtField.backgroundColor = UIColor.magenta
            txtField.placeholder = "Do you like me now..?"

    return txtField

}

The reason behind the custombttn(theSelector:Selector), is that i want to pass the function dynamically to the button in my viewcontroller file.

Now, moving the fileB.swift, I have the following code...

class TabOneViewController: UIViewController{

    let txt = customtxtfld()
    let bttn = custombttn(theSelector: #selector(updatetxt))

    override func loadView() {

        super.loadView()

            view.addSubview(txt)
                view.addSubview(bttn)

    }

     func updatetxt(){

        txt.text = "hello, you!"
    }

}

Here is where things get tricky, when I attempt to build, I don't get any error (not even a warning). However, when I run the app, and tap the bttn in fileB.swift, I get the following error during runtime:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButton updatetxt]: unrecognized selector sent to instance 0x7f8453415670'

If I have 2 or more functions in my fileB.swift that I wish to assign dynamically to the action part of the addTarget, is there any way I can pass the selector dynamically to a button..?

Appreciate your time and assistance. Please let me know if I need to explain something further.


Solution

  • It's crashing because your button target is wrong.

    func custombttn(target:Any, theSelector:Selector)-> UIButton{
    
        let bttn = UIButton(frame: CGRect(x:20, y:400, width:200, height:30))
        bttn.setTitle("tap this button", for: UIControlState.normal)
        bttn.backgroundColor = UIColor.black
        bttn.setTitleColor(UIColor.magenta, for: UIControlState.normal)
        bttn.addTarget(target, action: theSelector, for: UIControlEvents.touchUpInside)        
        return bttn        
    }
    

    And use it like this

    class TabOneViewController: UIViewController{
    
        let txt = customtxtfld()
    
        override func loadView() {
    
            super.loadView()
    
                view.addSubview(txt)
    
                let bttn = custombttn(target:self,  theSelector: #selector(updatetxt))
                view.addSubview(bttn)
    
        }
    
         func updatetxt(){
    
            txt.text = "hello, you!"
        }
    
    }