-1

I have the below Swift 2 code set up that captures all touches across the whole app. It alerts when touches are occurring and when touches have stopped.

I am wanting to access two functions in another view controller named myVC when touches are occurring and when they’ve stopped, calling function one funcOne() and function two funcTwo(). However I continuously get an error fatal error: unexpectedly found nil while unwrapping an Optional value. It seems whenever myVC is called, it causes errors.

How can I achieve calling a function on the ViewController without errors and please depending on when the app is receiving or not receiving any touch events in Swift 2 please?

main.swift file:

import UIKit

UIApplicationMain(Process.argc, Process.unsafeArgv, nil, NSStringFromClass(AppDelegate))

UIApplication.swift file:

import UIKit

@objc(MyApplication)

class MyApplication: UIApplication {

var myVC: ViewController!

    override func sendEvent(event: UIEvent) {

        if event.type != .Touches {
            super.sendEvent(event)
            return
        }

        var touchesStarted = false
        if let touches = event.allTouches() {
            for touch in touches.enumerate() {
                if touch.element.phase != .Cancelled && touch.element.phase != .Ended {
                    touchesStarted = true
                    break
                }
            }
        }

        if touchesStarted {
    myVC.funcOne()  // Call function one on ViewController
        } else {
    myVC.funcTwo() // Call function two on ViewController
        }

        super.sendEvent(event)
    }
}
user4806509
  • 2,925
  • 5
  • 37
  • 72

1 Answers1

1

The problem is that you are saying

 var myVC: ViewController!

but you are never setting that variable myVC to any value (i.e. an existing ViewController instance). Thus it is always nil, and so when you refer to it in your code, you crash.

My advice would be that this view controller, in its own viewDidLoad, should say

(UIApplication.sharedApplication() as MyApplication).myVC = self
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • By the way, what you're doing is a really bad idea, and it's totally unnecessary. You could more safely intervene in touch handling by subclassing UIWindow instead of UIApplication, or even better, intervene at the level of the view controller by means of an invisible view in front of everything. – matt Mar 29 '16 at 17:38
  • Thanks, @Matt. How can I set a variable for myVC to a value? – user4806509 Mar 29 '16 at 17:46
  • I've tried `UIWindow`, but it doesn't work for all gestures and touches combined. `UIApplication` does work however using `print` to test it. However I need to set a function going in the ViewController. – user4806509 Mar 29 '16 at 17:48
  • You say `myVC = theViewController`. But getting a reference to the actual view controller is your problem; I have no notion of where it is in your view controller hierarchy — it's _your_ app! My advice would be that the view controller itself in its own `viewDidLoad` should do this, since it can see the application: `(UIApplication.sharedApplication() as MyApplication).myVC = self` – matt Mar 29 '16 at 17:52
  • Huzzah! Progress, all is working. Thank you very kindly! – user4806509 Mar 29 '16 at 18:34
  • PS @matt I'm interested to understand a bit more about why doing this is a really bad idea and the safety issues around it if you could please elaborate? I did at one point consider an invisible uiview, but didn't know exactly how to achieve that. – user4806509 Mar 29 '16 at 18:51