This file contains 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