Hey,
It seems like you're missing some of the conceptual basics regarding Cocoa's target-action system. The target
is supposed to be the actual object your function exists and should be called on, the action
is just essentially the name of the function. When you pass self
as the target and #selector(context.coordinator.cancelButtonTapped(button:))
as your action, then the context.coordinator.
part of the selector only helps the Swift compiler check that such a function exists, but it doesn't tell Cocoa to look there for it. To make it work, you need to pass context.coordinator
as your target:
let cancelButton = UIBarButtonItem(title: "Cancel", style: .done, target: context.coordinator, action: #selector(context.coordinator.cancelButtonTapped(button:)))
let clearButton = UIBarButtonItem(title: "Clear", style: .done, target: context.coordinator, action: #selector(context.coordinator.clearButtonTapped(button:)))
let doneButton = UIBarButtonItem(title: "Done", style: .done, target: context.coordinator, action: #selector(context.coordinator.doneButtonTapped(button:)))
But since you don't seem to have much experience with target-action, I suggest you take a look at the "new" UIAction
api. This lets you use normal closures as onclick methods for buttons, which makes it a lot easier to use IMO. Here's what the above buttons would look like with it (I chose to show a different approach for each button, just so you get to pick which would suit you best):
let cancelButton = UIBarButtonItem(title: "Cancel", image: nil, primaryAction: UIAction { action in
context.coordinator.cancelButtonTapped(action: action)
})
let clearButton = UIBarButtonItem(title: "Clear", image: nil, primaryAction: UIAction(handler: context.coordinator.clearButtonTapped(action:)))
let doneButton = UIBarButtonItem(title: "Done", image: nil, primaryAction: context.coordinator.doneAction)
...
class Coordinator: NSObject, UITextFieldDelegate {
lazy var doneAction = UIAction(handler: doneButtonTapped(action:))
...
func cancelButtonTapped(action: UIAction) -> Void {
print("Cancel Button Tapped")
}
func clearButtonTapped(action: UIAction) -> Void {
print("Clear Button Tapped")
}
private func doneButtonTapped(action: UIAction) -> Void {
print("Done Button Tapped")
}
}
Target-action is of course still a very valid approach, just throught I'd throw this here for completeness.