Created
May 16, 2016 07:38
-
-
Save ryangibson/72c8fe7f7514c9467fdfe79d5010c3a1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // MARK: Protocols | |
| protocol ResponderProtocol { | |
| var nextResponder: ResponderProtocol? { get } | |
| } | |
| protocol CopyProtocol { | |
| func copy() | |
| } | |
| // MARK: Concrete responder | |
| class Responder: ResponderProtocol { | |
| var nextResponder: ResponderProtocol? | |
| } | |
| // MARK: Responder chain classes | |
| class Button: Responder {} | |
| class View: Responder {} | |
| class CopyableView: Responder, CopyProtocol { | |
| func copy() { | |
| print("Copied copyable view") | |
| } | |
| } | |
| class Window: Responder, CopyProtocol { | |
| func copy() { | |
| print("Copied window") | |
| } | |
| } | |
| // MARK: Walk responder chain helper | |
| func walkResponderChain(firstResponder: ResponderProtocol?, handleEvent: (ResponderProtocol) -> Bool) -> ResponderProtocol? { | |
| guard let responder = firstResponder else { | |
| return nil | |
| } | |
| guard handleEvent(responder) == false else { | |
| // Responder handled our call | |
| return responder | |
| } | |
| return walkResponderChain(responder.nextResponder, handleEvent: handleEvent) | |
| } | |
| // MARK: Copy via responder chain | |
| func copy(firstResponder: ResponderProtocol) -> ResponderProtocol? { | |
| return walkResponderChain(firstResponder) { responder in | |
| if let validResponder = responder as? CopyProtocol { | |
| validResponder.copy() | |
| return true | |
| } | |
| return false | |
| } | |
| } | |
| // Test case | |
| let button = Button() | |
| let view = View() | |
| let copyView = CopyableView() | |
| let window = Window() | |
| // Setup responder chain as Button -> CopyableView -> Window | |
| button.nextResponder = copyView | |
| view.nextResponder = window | |
| copyView.nextResponder = window | |
| copy(button) | |
| // Setup responder chain as Button -> View -> Window | |
| button.nextResponder = view | |
| copy(button) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment