Reputation: 13
I'm trying to set an action to call on a button touch. I created the button in IB, and in the main class I'm trying to set the needed action.
After all set up, I touch the button and nothing happens. I guess there is a problem with target or action selector: which in this case I should use? Thanks!
class View: UIView {
private class PhoneCallSetter: UIResponder {
private var phone: String!
func initialize(button: UIButton!, phoneNumber: String!) {
self.phone = phoneNumber
button.addTarget(self, action: #selector(PhoneCallSetter.call), forControlEvents: UIControlEvents.TouchUpInside)
}
@objc func call() {
if let phoneCallURL: NSURL = NSURL(string: "tel://\(phone)") {
let application: UIApplication = UIApplication.sharedApplication()
if (application.canOpenURL(phoneCallURL)) {
application.openURL(phoneCallURL);
}
}
}
}
@IBOutlet weak var button: UIButton!
// somewhere down there I call
func setPhone() {
PhoneCallSetter().initialize(button, phoneNumber: "123-456")
}}
Upvotes: 0
Views: 451
Reputation: 7
Try to change the name of button outlet here:
@IBOutlet weak var button: UIButton!
your function
func initialize(button: UIButton!, phoneNumber: String!)
is not able to recognise the actual button pressed, as you have the button name same at both the places.
Upvotes: 0
Reputation: 175
your target in inner class should be nested(inherited)
button.addTarget(View. PhoneCallSetter, action: #selector(PhoneCallSetter.call), forControlEvents: UIControlEvents.TouchUpInside)
something like this.
Upvotes: 0
Reputation: 47876
In your setPhone()
method, you create a new instance of PhoneCallSetter
, and calling its method initialize(_:phoneNumber:)
, but you are not keeping the instance anywhere.
For an object to be an action target, the object needs to be kept somewhere with a strong reference. UIButton
(or any other UIControl
) just holds the target object with weak reference.
Which means, once the method initialize(_:phoneNumber:)
has finished execution, the instance of PhoneCallSetter
is released. An action method sent to already released instance may be ignored silently.
Thus, you need to keep the instance with strong reference, such as:
var phoneCallSetter: PhoneCallSetter?
func setPhone() {
self.phoneCallSetter = PhoneCallSetter()
self.phoneCallSetter!.initialize(button, phoneNumber: "123-456")
}
But I do not understand why you dare make a private class as an action target. Non-standard way forces you to make non-standard effort, which you'd better avoid.
Upvotes: 1
Reputation: 131418
It looks to me like the problem is your setPhone()
function. That function creates a new instance of your PhoneCallSetter
class and then calls it's initialize method, but you then never do anything with that object. You should either create a UIView object in your storyboard and change it's class to PhoneCallSetter
(probably best) or add a PhoneCallSetter object to your view hierarchy in code. (But that would mean setting up constraints on it, which is a little tricky.)
Upvotes: 0
Reputation: 1321
For Example:
class FV_OrderComplete: UIView {
var block_OrderSubmit: (() -> ())!
var block_checkPincode: ((String) -> ())!
@IBAction func didActButtonOK(_ sender: AnyObject)
{
if block_OrderSubmit != nil{
block_OrderSubmit()
}
if block_checkPincode != nil{
block_checkPincode(txtField_Pincode.text!)
}
}
}
In Controller class use the block where you want. It will only call when you press the button:
self.vew.block_OrderSubmit =
{
()in
//write code
}
self.vew.block_checkPincode =
{
(str_Pincode: String) in
//write code and use the passed data
}
Note: Here vew is object of UIView class.
Upvotes: 0