Skip to content

Instantly share code, notes, and snippets.

@JunyuKuang
Last active June 2, 2020 05:56
Show Gist options
  • Save JunyuKuang/057d8af9e3b3d2a7a516ea11f94f12dd to your computer and use it in GitHub Desktop.
Save JunyuKuang/057d8af9e3b3d2a7a516ea11f94f12dd to your computer and use it in GitHub Desktop.
//
// UIKeyCommand+Closure.swift
//
// Created by Jonny Kuang.
// Copyright © 2018 Jonny Kuang. All rights reserved.
//
import UIKit
protocol KeyCommandsProvider {
func makeKeyCommands() -> [UIKeyCommand]
}
protocol KeyCommandInput {
var keyCommandInput: String { get }
}
extension KeyCommandInput where Self : RawRepresentable, Self.RawValue == String {
var keyCommandInput: String { return rawValue }
}
extension UIKeyCommand {
typealias Handler = (UIKeyCommand) -> Void
convenience init(input: String, modifiers: UIKeyModifierFlags = [], title: String = "", handler: @escaping Handler) {
self.init(input: input, modifierFlags: modifiers, action: #selector(UIWindow.handleClosureBasedKeyCommand))
self.title = title
register(handler)
}
convenience init(input: Input, modifiers: UIKeyModifierFlags = [], title: String = "", handler: @escaping Handler) {
self.init(input: input.keyCommandInput, modifiers: modifiers, title: title, handler: handler)
}
convenience init(input: KeyCommandInput, modifiers: UIKeyModifierFlags = [], title: String = "", handler: @escaping Handler) {
self.init(input: input.keyCommandInput, modifiers: modifiers, title: title, handler: handler)
}
var modifiers: UIKeyModifierFlags {
return modifierFlags
}
var title: String {
get { return discoverabilityTitle ?? "" }
set { discoverabilityTitle = newValue.isEmpty ? nil : newValue }
}
enum Input : String, KeyCommandInput {
case upArrow
case downArrow
case leftArrow
case rightArror
case escape
var rawValue: String {
switch self {
case .upArrow: return UIKeyCommand.inputUpArrow
case .downArrow: return UIKeyCommand.inputDownArrow
case .leftArrow: return UIKeyCommand.inputLeftArrow
case .rightArror: return UIKeyCommand.inputRightArrow
case .escape: return UIKeyCommand.inputEscape
}
}
init?(rawValue: String) {
fatalError("init(rawValue:) has not been implemented")
}
}
}
private extension UIWindow {
@objc func handleClosureBasedKeyCommand(_ command: UIKeyCommand) {
command.handle()
}
}
private extension UIKeyCommand {
typealias Identifier = String
var identifier: Identifier {
let input = self.input ?? ""
let modifiers = "\(modifierFlags.rawValue)"
return input + " " + modifiers
}
static var handlersByIdentifiers = [Identifier : Handler]()
func register(_ handler: @escaping UIKeyCommand.Handler) {
UIKeyCommand.handlersByIdentifiers[identifier] = handler
}
func handle() {
UIKeyCommand.handlersByIdentifiers[identifier]?(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment