Engineering

Iterating ResponderChain

ResponderChain is used event handling.

UIResponder class has following method.
We can get next responder.

func next() -> UIResponder?

UIViewController and UIView has inherited UIResponder class.
Calling next() recursively can get UIApplication has UIWindow.

I've created following code. This iterate responder object.

final class ResponderChainIterator: IteratorProtocol, Sequence {

  typealias Element = UIResponder

  private var currentResponder: UIResponder?

  init(responder: UIResponder) {
    currentResponder = responder
  }

  func next() -> UIResponder? {
    let next = currentResponder?.next
    currentResponder = next
    return next
  }
}

We can find ViewController it has tapped UIButton.

let button: UIButton

let viewController = ResponderChainIterator(responder: view)
  .flatMap { $0 as? UIViewController }
  .first