Latenec
Latenec

Reputation: 418

Track all user touches in the application Swift

I’m searching about a week on stackoverflow regarding the issue that I want to track all user touches, but without success I know there are many questions opened like this but not specifically what I’m looking for.

What I want to have: Track all user touches, that includes for example UIButton was pressed or UITextfield was pressed or some ViewController was opened and so on. BUT: why this question is different, I want to have some label text that explains which exact button was pressed for example if I have LoginVC and there is Sign in button, I want the method to explain that "Sign In button was pressed” or "Forgot button was pressed” and then to log this events/touches.

Thanks in advance!

Upvotes: 3

Views: 1545

Answers (1)

AamirR
AamirR

Reputation: 12198

You can create a BaseViewController, and add a tap gesture recognizer to its view, and than determine which subview was tapped, as such:

class BaseViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewDidTap(_:)))
        tapRecognizer.delegate = self
        tapRecognizer.cancelsTouchesInView = false
        self.view.addGestureRecognizer(tapRecognizer)
    }

    @objc func viewDidTap(_ recognizer: UITapGestureRecognizer) {
        guard let view = recognizer.view else { return }

        let location = recognizer.location(in: view)
        let subview = view.hitTest(location, with: nil)
        self.log(tappedView: subview ?? view)
    }

    func log(tappedView: UIView) {
        // do some base job with the tapped view
    }

}

extension BaseViewController: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        let location = gestureRecognizer.location(in: self.view)
        guard let textField = self.view.hitTest(location, with: nil) as? UITextField else { return false }

        textField.becomeFirstResponder()
        return true
    }
}

Now you can extend other viewcontrollers to have BaseViewController's functionality and override the log method, as such:

class ChildViewController: BaseViewController {

    let forgotButton = UIButton()
    let signinButton = UIButton()

    override func log(tappedView: UIView) {
        super.log(tappedView: tappedView)

        if (tappedView === self.forgotButton) {
            labelLog.text = "Forgot button was tapped"
        } else if (tappedView === self.signinButton) {
            labelLog.text = "Sign In button was tapped"
        }
    }
}

Upvotes: 5

Related Questions