Home telegram-keyShortcut
Post
Cancel

telegram-keyShortcut

KeyShortcutResponder

struct KeyShortcut

1
2
3
4
let title: String
let input: String
let modifiers: UIKeyModifierFlags
let action: () -> Void

protocol KeyShortcutResponder

1
var keyShortcuts: [KeyShortcut] { get };

class KeyShortcutsController:UIResponder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
private var effectiveShortcuts: [KeyShortcut]?
private var viewControllerEnumerator: (@escaping (ContainableController) -> Bool) -> Void

public static var isAvailable: Bool {
    if #available(iOSApplicationExtension 8.0, iOS 8.0, *), UIDevice.current.userInterfaceIdiom == .pad {
        return true
    } else {
        return false
    }
}

public init(enumerator: @escaping (@escaping (ContainableController) -> Bool) -> Void) {
    self.viewControllerEnumerator = enumerator
    super.init()
}

// key commands
public override var keyCommands: [UIKeyCommand]? {
    var convertedCommands: [UIKeyCommand] = []
    var shortcuts: [KeyShortcut] = []
    
    self.viewControllerEnumerator({ viewController -> Bool in
        guard let viewController = viewController as? KeyShortcutResponder else {
            return true
        }
        shortcuts.removeAll(where: { viewController.keyShortcuts.contains($0) })
        shortcuts.append(contentsOf: viewController.keyShortcuts)
        return true
    })
    
    convertedCommands.append(contentsOf: shortcuts.map { $0.uiKeyCommand })
    
    self.effectiveShortcuts = shortcuts
    
    return convertedCommands
}

// handle key command
@objc func handleKeyCommand(_ command: UIKeyCommand) {
    if let shortcut = findShortcut(for: command) {
        shortcut.action()
    }
}

// find shorcut for command
private func findShortcut(for command: UIKeyCommand) -> KeyShortcut? {
    if let shortcuts = self.effectiveShortcuts {
        for shortcut in shortcuts {
            if shortcut.isEqual(to: command) {
                return shortcut
            }
        }
    }
    return nil
}

// can perform action
public override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if let keyCommand = sender as? UIKeyCommand, let _ = findShortcut(for: keyCommand) {
        return true
    } else {
        return super.canPerformAction(action, withSender: sender)
    }
}

// targe for action
public override func target(forAction action: Selector, withSender sender: Any?) -> Any? {
    if let keyCommand = sender as? UIKeyCommand, let _ = findShortcut(for: keyCommand) {
        return self
    } else {
        return super.target(forAction: action, withSender: sender)
    }
}

// can become first responder
public override var canBecomeFirstResponder: Bool {
    return true
}
This post is licensed under CC BY 4.0 by the author.