skip to Main Content

In my last question I learned to put a timer on the game so that after the start button was clicked, the user would have to wait a few seconds to be able to touch the screen. That code looks like this:

self.view?.isUserInteractionEnabled = false
    DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
        self.view?.isUserInteractionEnabled = true
        
    }

I have kept the last post up for learning purposes for others. This time I am wondering how you would go about not allowing touch at all until a button is pressed! I switched the true statement above to "false", so the user cannot touch when first on the game. However, I want the user to be able to click the start button to then allow all other touch during the game. Thanks!

2

Answers


  1. A very simple way you could do this would be to create a subclass of UIView that overrides func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?.

    Then you simply check to see if the button has been pressed before forwarding events to other subviews.

    class View: UIView {
        
        private var hasTappedButton = false
        let button = UIButton()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            configureButton()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            configureButton()
        }
        
        private func configureButton() {
            button.addTarget(self, action: #selector(tappedButton), for: .touchUpInside)
        }
        
        override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            
            let view = super.hitTest(point, with: event)
            
            guard !hasTappedButton else { return view }
            
            return view == button ? button : nil
        }
        
        @objc private func tappedButton() {
            hasTappedButton = true
        }
    }
    
    Login or Signup to reply.
  2. I want the user to be able to click the start button to then allow all other touch during the game

    My solution is to place an invisible view in front of the entire interface and use hit-test munging so that only one view behind it (self.passthruView, your button) is touchable:

    class MyView: UIView {
        weak var passthruView : UIView?
        override func hitTest(_ point: CGPoint, with e: UIEvent?) -> UIView? {
            if let pv = self.passthruView {
                let pt = pv.convert(point, from: self)
                if pv.point(inside: pt, with: e) {
                    return nil
                }
            }
            return super.hitTest(point, with: e)
        }
    }
    

    So as long as MyView is sitting (invisibly) in front of the whole interface, only the button can be touched. Then you take away MyView and the whole interface becomes touchable again.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search