As the title says, I got this error message:
libc abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[{Project}.{UIView} tapAction:]: unrecognized selector sent to instance 0x156406c70'
terminating with uncaught exception of type NSException
When I was trying to customize a UIButton
like this:
class BaseButton: UIButton {
private var action: ((UIButton)->())?
public func tapInside(target: Any?, action: ((UIButton)->())?) {
self.action = action
self.addTarget(target, action: #selector(tapAction(_:)), for: .touchUpInside)
}
@objc private func tapAction(_ sender: UIButton) {
if let _f = action {
_f(self)
}
}
}
I understand that I was trying something advanced without understanding the basics.
Please let me know if there is any other solution that I don't have to create a tapAction
every time.
Update: Details added to error message.
CodePudding user response:
If you'd share the FULL error message, you should have:
-[TheClass tapAction:] unrecognized selector sent to instance
Where TheClass
should be the class of the instance that called tapInside(target:action:)
.
That's what might give you a tip on your issue.
Ie, TheClass
is calling on itself the method tapAction(_:)
, which is doesn't' know.
It's like writing theClass.tapAction(someSender)
, this shouldn't compile, right?
The issue, is that in addTarget(_:action:for:)
, the target
is the one that implement the action
(selector). In this case, it's self
, the BaseButton
instance.
So:
self.addTarget(target, action: #selector(tapAction(_:)), for: .touchUpInside)
=>
self.addTarget(self, action: #selector(tapAction(_:)), for: .touchUpInside)
Now, since you don't need anymore the target
parameter, you can remove it from the method:
public func tapInside(target: Any?, action: ((UIButton)->())?) {...}
=>
public func tapInside(action: ((UIButton)->())?) {...}