Search code examples
iosswiftuiresponder

Missing First Responder in iOS 11 with Swift 4 App (Xcode 9.X)?


I have a stripped down, code based test app (no Storyboard), that has:

  • UIWindow object
  • ViewController, with its main View
  • Single UIView object on top. -

To test which object is the first responder, i evaluate in tochesBegan, inside the topView as follows, but all items respond false. The Responder Chain is working because the touch is detected (both in the topView and in the main controller's view.

This is the stripped down version of the app. Given that this is not a simple view-subview hierarchy, I don't use a recursive function.

import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        window = UIWindow()
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
        return true
    }
}
class ViewController: UIViewController {
    override func viewDidLoad() {
        let topView = View()
        self.view.addSubview(topView)
    }
}
class View: UIView {
    convenience init() {
        self.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        self.backgroundColor = UIColor.yellow
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let window = (UIApplication.shared).delegate?.window as? UIWindow
        let viewController = window?.rootViewController
        let mainView = viewController?.view
        print("Window?: \(window!.isFirstResponder)")
        print("View Controller?: \(viewController!.isFirstResponder)")
        print("Main View?: \(mainView!.isFirstResponder)")
        for view in (mainView?.subviews)! {
            print("Any View?: \(view.isFirstResponder)")
        }
    }
}

All evaluations return false. Am I doing something wrong here?

Regards... e


Solution

  • I think there is no first responder from start. You can still receive events to your views.

    Responder object
    Mouse events and multitouch events first go to the view that is under the mouse pointer or finger; that view might or might not be the first responder.

    More on responders

    nextResponder
    The UIResponder class does not store or set the next responder automatically, so this method returns nil by default.

    More on nextResponder