0

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.

Gamal Elsayed
  • 63
  • 2
  • 10

2 Answers2

0

Yes, you can. The issue here is that you passed the button itself as the target for the action. Just pass the correct target when adding the action, which in this case is the instance of your view controller.

floschliep
  • 513
  • 5
  • 14
0

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!"
    }

}
Bilal
  • 18,478
  • 8
  • 57
  • 72
  • Appreciate your help. This worked. In 'Target:self', self refers to instance of the viewcontroller, correct? And thank you all for assistance. – Gamal Elsayed Jul 02 '17 at 14:45